]>
git.saurik.com Git - apt.git/blob - apt-pkg/orderlist.cc
984ae1d10400d312927dbe184770ff1ae8581432
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: orderlist.cc,v 1.14 2001/05/07 05:49:43 jgg Exp $
4 /* ######################################################################
6 Order List - Represents and Manipulates an ordered list of packages.
8 A list of packages can be ordered by a number of conflicting criteria
9 each given a specific priority. Each package also has a set of flags
10 indicating some useful things about it that are derived in the
11 course of sorting. The pkgPackageManager class uses this class for
12 all of it's installation ordering needs.
14 This is a modified version of Manoj's Routine B. It consists of four
15 independent ordering algorithms that can be applied at for different
16 points in the ordering. By appling progressivly fewer ordering
17 operations it is possible to give each consideration it's own
18 priority and create an order that satisfies the lowest applicable
21 The rules for unpacking ordering are:
22 1) Unpacking ignores Depends: on all packages
23 2) Unpacking requires Conflicts: on -ALL- packages to be satisfied
24 3) Unpacking requires PreDepends: on this package only to be satisfied
25 4) Removing requires that no packages depend on the package to be
28 And the rule for configuration ordering is:
29 1) Configuring requires that the Depends: of the package be satisfied
30 Conflicts+PreDepends are ignored because unpacking says they are
31 already correct [exageration, it does check but we need not be
34 And some features that are valuable for unpacking ordering.
35 f1) Unpacking a new package should advoid breaking dependencies of
37 f2) Removal should not require a force, corrolory of f1
38 f3) Unpacking should order by depends rather than fall back to random
41 Each of the features can be enabled in the sorting routine at an
42 arbitrary priority to give quite abit of control over the final unpacking
45 The rules listed above may never be violated and are called Critical.
46 When a critical rule is violated then a loop condition is recorded
47 and will have to be delt with in the caller.
49 The ordering keeps two lists, the main list and the 'After List'. The
50 purpose of the after list is to allow packages to be delayed. This is done
51 by setting the after flag on the package. Any package which requires this
52 package to be ordered before will inherit the after flag and so on. This
53 is used for CD swap ordering where all packages on a second CD have the
54 after flag set. This forces them and all their dependents to be ordered
57 There are complications in this algorithm when presented with cycles.
58 For all known practical cases it works, all cases where it doesn't work
59 is fixable by tweaking the package descriptions. However, it should be
60 possible to impove this further to make some better choices when
61 presented with cycles.
63 ##################################################################### */
65 // Include Files /*{{{*/
68 #include <apt-pkg/orderlist.h>
69 #include <apt-pkg/depcache.h>
70 #include <apt-pkg/error.h>
71 #include <apt-pkg/version.h>
72 #include <apt-pkg/sptr.h>
73 #include <apt-pkg/configuration.h>
80 pkgOrderList
*pkgOrderList::Me
= 0;
82 // OrderList::pkgOrderList - Constructor /*{{{*/
83 // ---------------------------------------------------------------------
85 pkgOrderList::pkgOrderList(pkgDepCache
*pCache
) : Cache(*pCache
),
86 Primary(NULL
), Secondary(NULL
),
87 RevDepends(NULL
), Remove(NULL
),
88 AfterEnd(NULL
), FileList(NULL
),
89 LoopCount(-1), Depth(0)
91 Debug
= _config
->FindB("Debug::pkgOrderList",false);
93 /* Construct the arrays, egcs 1.0.1 bug requires the package count
95 unsigned long Size
= Cache
.Head().PackageCount
;
96 Flags
= new unsigned short[Size
];
97 End
= List
= new Package
*[Size
];
98 memset(Flags
,0,sizeof(*Flags
)*Size
);
101 // OrderList::~pkgOrderList - Destructor /*{{{*/
102 // ---------------------------------------------------------------------
104 pkgOrderList::~pkgOrderList()
110 // OrderList::IsMissing - Check if a file is missing /*{{{*/
111 // ---------------------------------------------------------------------
113 bool pkgOrderList::IsMissing(PkgIterator Pkg
)
115 // Skip packages to erase
116 if (Cache
[Pkg
].Delete() == true)
119 // Skip Packages that need configure only.
120 if ((Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
||
121 Pkg
.State() == pkgCache::PkgIterator::NeedsNothing
) &&
122 Cache
[Pkg
].Keep() == true)
128 if (FileList
[Pkg
->ID
].empty() == false)
134 // OrderList::DoRun - Does an order run /*{{{*/
135 // ---------------------------------------------------------------------
136 /* The caller is expeted to have setup the desired probe state */
137 bool pkgOrderList::DoRun()
140 unsigned long Size
= Cache
.Head().PackageCount
;
141 SPtrArray
<Package
*> NList
= new Package
*[Size
];
142 SPtrArray
<Package
*> AfterList
= new Package
*[Size
];
143 AfterEnd
= AfterList
;
146 WipeFlags(Added
| AddPending
| Loop
| InList
);
148 for (iterator I
= List
; I
!= End
; ++I
)
151 // Rebuild the main list into the temp list.
152 iterator OldEnd
= End
;
154 for (iterator I
= List
; I
!= OldEnd
; ++I
)
155 if (VisitNode(PkgIterator(Cache
,*I
), "DoRun") == false)
161 // Copy the after list to the end of the main list
162 for (Package
**I
= AfterList
; I
!= AfterEnd
; I
++)
165 // Swap the main list to the new list
167 List
= NList
.UnGuard();
171 // OrderList::OrderCritical - Perform critical unpacking ordering /*{{{*/
172 // ---------------------------------------------------------------------
173 /* This performs predepends and immediate configuration ordering only.
174 This is termed critical unpacking ordering. Any loops that form are
175 fatal and indicate that the packages cannot be installed. */
176 bool pkgOrderList::OrderCritical()
180 Primary
= &pkgOrderList::DepUnPackPreD
;
188 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareB
);
190 if (DoRun() == false)
194 return _error
->Error("Fatal, predepends looping detected");
198 clog
<< "** Critical Unpack ordering done" << endl
;
200 for (iterator I
= List
; I
!= End
; ++I
)
202 PkgIterator
P(Cache
,*I
);
203 if (IsNow(P
) == true)
204 clog
<< " " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
211 // OrderList::OrderUnpack - Perform complete unpacking ordering /*{{{*/
212 // ---------------------------------------------------------------------
213 /* This performs complete unpacking ordering and creates an order that is
214 suitable for unpacking */
215 bool pkgOrderList::OrderUnpack(string
*FileList
)
217 this->FileList
= FileList
;
219 // Setup the after flags
224 // Set the inlist flag
225 for (iterator I
= List
; I
!= End
; ++I
)
227 PkgIterator
P(Cache
,*I
);
228 if (IsMissing(P
) == true && IsNow(P
) == true)
233 Primary
= &pkgOrderList::DepUnPackCrit
;
234 Secondary
= &pkgOrderList::DepConfigure
;
235 RevDepends
= &pkgOrderList::DepUnPackDep
;
236 Remove
= &pkgOrderList::DepRemove
;
241 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareA
);
244 clog
<< "** Pass A" << endl
;
245 if (DoRun() == false)
249 clog
<< "** Pass B" << endl
;
251 if (DoRun() == false)
255 clog
<< "** Pass C" << endl
;
258 Remove
= 0; // Otherwise the libreadline remove problem occures
259 if (DoRun() == false)
263 clog
<< "** Pass D" << endl
;
265 Primary
= &pkgOrderList::DepUnPackPre
;
266 if (DoRun() == false)
271 clog
<< "** Unpack ordering done" << endl
;
273 for (iterator I
= List
; I
!= End
; ++I
)
275 PkgIterator
P(Cache
,*I
);
276 if (IsNow(P
) == true)
277 clog
<< " " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
284 // OrderList::OrderConfigure - Perform configuration ordering /*{{{*/
285 // ---------------------------------------------------------------------
286 /* This orders by depends only and produces an order which is suitable
288 bool pkgOrderList::OrderConfigure()
291 Primary
= &pkgOrderList::DepConfigure
;
299 // OrderList::Score - Score the package for sorting /*{{{*/
300 // ---------------------------------------------------------------------
301 /* Higher scores order earlier */
302 int pkgOrderList::Score(PkgIterator Pkg
)
304 // Removals should be done after we dealt with essentials
305 static int const ScoreDelete
= _config
->FindI("OrderList::Score::Delete", 100);
306 if (Cache
[Pkg
].Delete() == true)
309 // This should never happen..
310 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
313 static int const ScoreEssential
= _config
->FindI("OrderList::Score::Essential", 200);
314 static int const ScoreImmediate
= _config
->FindI("OrderList::Score::Immediate", 10);
315 static int const ScorePreDepends
= _config
->FindI("OrderList::Score::PreDepends", 50);
318 if ((Pkg
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
319 Score
+= ScoreEssential
;
321 if (IsFlag(Pkg
,Immediate
) == true)
322 Score
+= ScoreImmediate
;
324 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();
325 D
.end() == false; ++D
)
326 if (D
->Type
== pkgCache::Dep::PreDepends
)
328 Score
+= ScorePreDepends
;
332 // Important Required Standard Optional Extra
333 if (Cache
[Pkg
].InstVerIter(Cache
)->Priority
<= 5)
335 signed short PrioMap
[] = {0,5,4,3,1,0};
336 Score
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
];
341 // OrderList::FileCmp - Compare by package file /*{{{*/
342 // ---------------------------------------------------------------------
343 /* This compares by the package file that the install version is in. */
344 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
)
346 if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true)
348 if (Cache
[A
].Delete() == true)
350 if (Cache
[B
].Delete() == true)
353 if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true)
355 if (Cache
[B
].InstVerIter(Cache
).FileList().end() == true)
358 pkgCache::PackageFile
*FA
= Cache
[A
].InstVerIter(Cache
).FileList().File();
359 pkgCache::PackageFile
*FB
= Cache
[B
].InstVerIter(Cache
).FileList().File();
367 // BoolCompare - Comparison function for two booleans /*{{{*/
368 // ---------------------------------------------------------------------
370 static int BoolCompare(bool A
,bool B
)
379 // OrderList::OrderCompareA - Order the installation by op /*{{{*/
380 // ---------------------------------------------------------------------
381 /* This provides a first-pass sort of the list and gives a decent starting
382 point for further complete ordering. It is used by OrderUnpack only */
383 int pkgOrderList::OrderCompareA(const void *a
, const void *b
)
385 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
386 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
388 // We order packages with a set state toward the front
390 if ((Res
= BoolCompare(Me
->IsNow(A
),Me
->IsNow(B
))) != 0)
393 // We order missing files to toward the end
394 /* if (Me->FileList != 0)
396 if ((Res = BoolCompare(Me->IsMissing(A),
397 Me->IsMissing(B))) != 0)
401 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
402 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
405 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
406 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
409 int ScoreA
= Me
->Score(A
);
410 int ScoreB
= Me
->Score(B
);
418 return strcmp(A
.Name(),B
.Name());
421 // OrderList::OrderCompareB - Order the installation by source /*{{{*/
422 // ---------------------------------------------------------------------
423 /* This orders by installation source. This is useful to handle
424 inter-source breaks */
425 int pkgOrderList::OrderCompareB(const void *a
, const void *b
)
427 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
428 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
430 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
431 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
434 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
435 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
438 int F
= Me
->FileCmp(A
,B
);
446 int ScoreA
= Me
->Score(A
);
447 int ScoreB
= Me
->Score(B
);
455 return strcmp(A
.Name(),B
.Name());
458 // OrderList::VisitDeps - Visit forward install dependencies /*{{{*/
459 // ---------------------------------------------------------------------
460 /* This calls the dependency function for the normal forwards dependencies
462 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
)
464 if (F
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer
== 0)
467 return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList());
470 // OrderList::VisitRDeps - Visit reverse dependencies /*{{{*/
471 // ---------------------------------------------------------------------
472 /* This calls the dependency function for all of the normal reverse depends
474 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
)
476 if (F
== 0 || Pkg
.end() == true)
479 return (this->*F
)(Pkg
.RevDependsList());
482 // OrderList::VisitRProvides - Visit provides reverse dependencies /*{{{*/
483 // ---------------------------------------------------------------------
484 /* This calls the dependency function for all reverse dependencies
485 generated by the provides line on the package. */
486 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
)
488 if (F
== 0 || Ver
.end() == true)
492 for (PrvIterator P
= Ver
.ProvidesList(); P
.end() == false; ++P
)
493 Res
&= (this->*F
)(P
.ParentPkg().RevDependsList());
497 // OrderList::VisitProvides - Visit all of the providing packages /*{{{*/
498 // ---------------------------------------------------------------------
499 /* This routine calls visit on all providing packages.
501 If the dependency is negative it first visits packages which are
502 intended to be removed and after that all other packages.
503 It does so to avoid situations in which this package is used to
504 satisfy a (or-group/provides) dependency of another package which
505 could have been satisfied also by upgrading another package -
506 otherwise we have more broken packages dpkg needs to auto-
507 deconfigure and in very complicated situations it even decides
509 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
)
511 SPtrArray
<Version
*> List
= D
.AllTargets();
512 for (Version
**I
= List
; *I
!= 0; ++I
)
514 VerIterator
Ver(Cache
,*I
);
515 PkgIterator Pkg
= Ver
.ParentPkg();
517 if (D
.IsNegative() == true && Cache
[Pkg
].Delete() == false)
520 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
523 if (D
.IsNegative() == false &&
524 Cache
[Pkg
].InstallVer
!= *I
)
527 if (D
.IsNegative() == true &&
528 (Version
*)Pkg
.CurrentVer() != *I
)
531 // Skip over missing files
532 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
535 if (VisitNode(Pkg
, "Provides-1") == false)
538 if (D
.IsNegative() == false)
540 for (Version
**I
= List
; *I
!= 0; ++I
)
542 VerIterator
Ver(Cache
,*I
);
543 PkgIterator Pkg
= Ver
.ParentPkg();
545 if (Cache
[Pkg
].Delete() == true)
548 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
551 if ((Version
*)Pkg
.CurrentVer() != *I
)
554 // Skip over missing files
555 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
558 if (VisitNode(Pkg
, "Provides-2") == false)
565 // OrderList::VisitNode - Recursive ordering director /*{{{*/
566 // ---------------------------------------------------------------------
567 /* This is the core ordering routine. It calls the set dependency
568 consideration functions which then potentialy call this again. Finite
569 depth is achived through the colouring mechinism. */
570 bool pkgOrderList::VisitNode(PkgIterator Pkg
, char const* from
)
572 // Looping or irrelevent.
573 // This should probably trancend not installed packages
574 if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||
575 IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false)
580 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
581 clog
<< "Visit " << Pkg
.FullName() << " from " << from
<< endl
;
587 Flag(Pkg
,AddPending
);
589 DepFunc Old
= Primary
;
591 // Perform immedate configuration of the package if so flagged.
592 if (IsFlag(Pkg
,Immediate
) == true && Primary
!= &pkgOrderList::DepUnPackPre
)
593 Primary
= &pkgOrderList::DepUnPackPreD
;
595 if (IsNow(Pkg
) == true)
598 if (Cache
[Pkg
].Delete() == false)
601 Res
&= Res
&& VisitDeps(Primary
,Pkg
);
602 Res
&= Res
&& VisitRDeps(Primary
,Pkg
);
603 Res
&= Res
&& VisitRProvides(Primary
,Pkg
.CurrentVer());
604 Res
&= Res
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
));
607 Res
&= Res
&& VisitRDeps(RevDepends
,Pkg
);
608 Res
&= Res
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer());
609 Res
&= Res
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
));
612 Res
&= Res
&& VisitDeps(Secondary
,Pkg
);
613 Res
&= Res
&& VisitRDeps(Secondary
,Pkg
);
614 Res
&= Res
&& VisitRProvides(Secondary
,Pkg
.CurrentVer());
615 Res
&= Res
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
));
620 Res
&= Res
&& VisitRDeps(Remove
,Pkg
);
621 Res
&= Res
&& VisitRProvides(Remove
,Pkg
.CurrentVer());
625 if (IsFlag(Pkg
,Added
) == false)
627 Flag(Pkg
,Added
,Added
| AddPending
);
628 if (IsFlag(Pkg
,After
) == true)
639 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
640 clog
<< "Leave " << Pkg
.FullName() << ' ' << IsFlag(Pkg
,Added
) << ',' << IsFlag(Pkg
,AddPending
) << endl
;
646 // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
647 // ---------------------------------------------------------------------
648 /* Critical unpacking ordering strives to satisfy Conflicts: and
649 PreDepends: only. When a prdepends is encountered the Primary
650 DepFunc is changed to be DepUnPackPreD.
652 Loops are preprocessed and logged. */
653 bool pkgOrderList::DepUnPackCrit(DepIterator D
)
655 for (; D
.end() == false; ++D
)
657 if (D
.Reverse() == true)
659 /* Reverse depenanices are only interested in conflicts,
660 predepend breakage is ignored here */
661 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
662 D
->Type
!= pkgCache::Dep::Obsoletes
)
665 // Duplication elimination, consider only the current version
666 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
669 /* For reverse dependencies we wish to check if the
670 dependency is satisifed in the install state. The
671 target package (caller) is going to be in the installed
673 if (CheckDep(D
) == true)
676 if (VisitNode(D
.ParentPkg(), "UnPackCrit") == false)
681 /* Forward critical dependencies MUST be correct before the
682 package can be unpacked. */
683 if (D
.IsNegative() == false &&
684 D
->Type
!= pkgCache::Dep::PreDepends
)
687 /* We wish to check if the dep is okay in the now state of the
688 target package against the install state of this package. */
689 if (CheckDep(D
) == true)
691 /* We want to catch predepends loops with the code below.
692 Conflicts loops that are Dep OK are ignored */
693 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
694 D
->Type
!= pkgCache::Dep::PreDepends
)
698 // This is the loop detection
699 if (IsFlag(D
.TargetPkg(),Added
) == true ||
700 IsFlag(D
.TargetPkg(),AddPending
) == true)
702 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
707 /* Predepends require a special ordering stage, they must have
708 all dependents installed as well */
709 DepFunc Old
= Primary
;
711 if (D
->Type
== pkgCache::Dep::PreDepends
)
712 Primary
= &pkgOrderList::DepUnPackPreD
;
713 Res
= VisitProvides(D
,true);
722 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
723 // ---------------------------------------------------------------------
724 /* Critical PreDepends (also configure immediate and essential) strives to
725 ensure not only that all conflicts+predepends are met but that this
726 package will be immediately configurable when it is unpacked.
727 Loops are preprocessed and logged. */
728 bool pkgOrderList::DepUnPackPreD(DepIterator D
)
730 if (D
.Reverse() == true)
731 return DepUnPackCrit(D
);
733 for (; D
.end() == false; ++D
)
735 if (D
.IsCritical() == false)
738 /* We wish to check if the dep is okay in the now state of the
739 target package against the install state of this package. */
740 if (CheckDep(D
) == true)
742 /* We want to catch predepends loops with the code below.
743 Conflicts loops that are Dep OK are ignored */
744 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
745 D
->Type
!= pkgCache::Dep::PreDepends
)
749 // This is the loop detection
750 if (IsFlag(D
.TargetPkg(),Added
) == true ||
751 IsFlag(D
.TargetPkg(),AddPending
) == true)
753 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
758 if (VisitProvides(D
,true) == false)
764 // OrderList::DepUnPackPre - Critical Predepends ordering /*{{{*/
765 // ---------------------------------------------------------------------
766 /* Critical PreDepends (also configure immediate and essential) strives to
767 ensure not only that all conflicts+predepends are met but that this
768 package will be immediately configurable when it is unpacked.
770 Loops are preprocessed and logged. All loops will be fatal. */
771 bool pkgOrderList::DepUnPackPre(DepIterator D
)
773 if (D
.Reverse() == true)
776 for (; D
.end() == false; ++D
)
778 /* Only consider the PreDepends or Depends. Depends are only
779 considered at the lowest depth or in the case of immediate
781 if (D
->Type
!= pkgCache::Dep::PreDepends
)
783 if (D
->Type
== pkgCache::Dep::Depends
)
785 if (Depth
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false)
792 /* We wish to check if the dep is okay in the now state of the
793 target package against the install state of this package. */
794 if (CheckDep(D
) == true)
796 /* We want to catch predepends loops with the code below.
797 Conflicts loops that are Dep OK are ignored */
798 if (IsFlag(D
.TargetPkg(),AddPending
) == false)
802 // This is the loop detection
803 if (IsFlag(D
.TargetPkg(),Added
) == true ||
804 IsFlag(D
.TargetPkg(),AddPending
) == true)
806 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
811 if (VisitProvides(D
,true) == false)
817 // OrderList::DepUnPackDep - Reverse dependency considerations /*{{{*/
818 // ---------------------------------------------------------------------
819 /* Reverse dependencies are considered to determine if unpacking this
820 package will break any existing dependencies. If so then those
821 packages are ordered before this one so that they are in the
824 The forwards depends loop is designed to bring the packages dependents
825 close to the package. This helps reduce deconfigure time.
827 Loops are irrelevent to this. */
828 bool pkgOrderList::DepUnPackDep(DepIterator D
)
831 for (; D
.end() == false; ++D
)
832 if (D
.IsCritical() == true)
834 if (D
.Reverse() == true)
836 /* Duplication prevention. We consider rev deps only on
837 the current version, a not installed package
839 if (D
.ParentPkg()->CurrentVer
== 0 ||
840 D
.ParentPkg().CurrentVer() != D
.ParentVer())
843 // The dep will not break so it is irrelevent.
844 if (CheckDep(D
) == true)
847 // Skip over missing files
848 if (IsMissing(D
.ParentPkg()) == true)
851 if (VisitNode(D
.ParentPkg(), "UnPackDep-Parent") == false)
856 if (D
->Type
== pkgCache::Dep::Depends
)
857 if (VisitProvides(D
,false) == false)
860 if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
862 if (CheckDep(D
) == true)
865 if (VisitNode(D
.TargetPkg(), "UnPackDep-Target") == false)
873 // OrderList::DepConfigure - Configuration ordering /*{{{*/
874 // ---------------------------------------------------------------------
875 /* Configuration only ordering orders by the Depends: line only. It
876 orders configuration so that when a package comes to be configured it's
877 dependents are configured.
879 Loops are ingored. Depends loop entry points are chaotic. */
880 bool pkgOrderList::DepConfigure(DepIterator D
)
882 // Never consider reverse configuration dependencies.
883 if (D
.Reverse() == true)
886 for (; D
.end() == false; ++D
)
887 if (D
->Type
== pkgCache::Dep::Depends
)
888 if (VisitProvides(D
,false) == false)
893 // OrderList::DepRemove - Removal ordering /*{{{*/
894 // ---------------------------------------------------------------------
895 /* Checks all given dependencies if they are broken by the remove of a
896 package and if so fix it by visiting another provider or or-group
897 member to ensure that the dependee keeps working which is especially
898 important for Immediate packages like e.g. those depending on an
899 awk implementation. If the dependency can't be fixed with another
900 package this means an upgrade of the package will solve the problem. */
901 bool pkgOrderList::DepRemove(DepIterator Broken
)
903 if (Broken
.Reverse() == false)
906 for (; Broken
.end() == false; ++Broken
)
908 if (Broken
->Type
!= pkgCache::Dep::Depends
&&
909 Broken
->Type
!= pkgCache::Dep::PreDepends
)
912 PkgIterator BrokenPkg
= Broken
.ParentPkg();
913 // uninstalled packages can't break via a remove
914 if (BrokenPkg
->CurrentVer
== 0)
917 // if its already added, we can't do anything useful
918 if (IsFlag(BrokenPkg
, AddPending
) == true || IsFlag(BrokenPkg
, Added
) == true)
921 // if the dependee is going to be removed, visit it now
922 if (Cache
[BrokenPkg
].Delete() == true)
923 return VisitNode(BrokenPkg
, "Remove-Dependee");
925 // The package stays around, so find out how this is possible
926 for (DepIterator D
= BrokenPkg
.CurrentVer().DependsList(); D
.end() == false;)
928 // only important or-groups need fixing
929 if (D
->Type
!= pkgCache::Dep::Depends
&&
930 D
->Type
!= pkgCache::Dep::PreDepends
)
936 // Start is the beginning of the or-group, D is the first one after or
937 DepIterator Start
= D
;
938 bool foundBroken
= false;
939 for (bool LastOR
= true; D
.end() == false && LastOR
== true; ++D
)
941 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
946 // this or-group isn't the broken one: keep searching
947 if (foundBroken
== false)
950 // iterate over all members of the or-group searching for a ready replacement
951 bool readyReplacement
= false;
952 for (DepIterator OrMember
= Start
; OrMember
!= D
&& readyReplacement
== false; ++OrMember
)
954 Version
** Replacements
= OrMember
.AllTargets();
955 for (Version
**R
= Replacements
; *R
!= 0; ++R
)
957 VerIterator
Ver(Cache
,*R
);
958 // only currently installed packages can be a replacement
959 PkgIterator RPkg
= Ver
.ParentPkg();
960 if (RPkg
.CurrentVer() != Ver
)
963 // packages going to be removed can't be a replacement
964 if (Cache
[RPkg
].Delete() == true)
967 readyReplacement
= true;
970 delete[] Replacements
;
973 // something else is ready to take over, do nothing
974 if (readyReplacement
== true)
977 // see if we can visit a replacement
978 bool visitReplacement
= false;
979 for (DepIterator OrMember
= Start
; OrMember
!= D
&& visitReplacement
== false; ++OrMember
)
981 Version
** Replacements
= OrMember
.AllTargets();
982 for (Version
**R
= Replacements
; *R
!= 0; ++R
)
984 VerIterator
Ver(Cache
,*R
);
985 // consider only versions we plan to install
986 PkgIterator RPkg
= Ver
.ParentPkg();
987 if (Cache
[RPkg
].Install() == false || Cache
[RPkg
].InstallVer
!= Ver
)
990 // loops are not going to help us, so don't create them
991 if (IsFlag(RPkg
, AddPending
) == true)
994 if (IsMissing(RPkg
) == true)
997 visitReplacement
= true;
998 if (IsFlag(BrokenPkg
, Immediate
) == false)
1000 if (VisitNode(RPkg
, "Remove-Rep") == true)
1005 Flag(RPkg
, Immediate
);
1006 if (VisitNode(RPkg
, "Remove-ImmRep") == true)
1009 visitReplacement
= false;
1011 delete[] Replacements
;
1013 if (visitReplacement
== true)
1016 // the broken package in current version can't be fixed, so install new version
1017 if (IsMissing(BrokenPkg
) == true)
1020 if (VisitNode(BrokenPkg
, "Remove-Upgrade") == false)
1028 // OrderList::AddLoop - Add a loop to the loop list /*{{{*/
1029 // ---------------------------------------------------------------------
1030 /* We record the loops. This is a relic since loop breaking is done
1031 genericaly as part of the safety routines. */
1032 bool pkgOrderList::AddLoop(DepIterator D
)
1034 if (LoopCount
< 0 || LoopCount
>= 20)
1040 if (Loops
[LoopCount
- 1].ParentPkg() == D
.ParentPkg() ||
1041 Loops
[LoopCount
- 1].TargetPkg() == D
.ParentPkg())
1045 Loops
[LoopCount
++] = D
;
1047 // Mark the packages as being part of a loop.
1048 //Flag(D.TargetPkg(),Loop);
1049 //Flag(D.ParentPkg(),Loop);
1050 /* This is currently disabled because the Loop flag is being used for
1051 loop management in the package manager. Check the orderlist.h file for more info */
1055 // OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/
1056 // ---------------------------------------------------------------------
1058 void pkgOrderList::WipeFlags(unsigned long F
)
1060 unsigned long Size
= Cache
.Head().PackageCount
;
1061 for (unsigned long I
= 0; I
!= Size
; I
++)
1065 // OrderList::CheckDep - Check a dependency for truth /*{{{*/
1066 // ---------------------------------------------------------------------
1067 /* This performs a complete analysis of the dependency wrt to the
1068 current add list. It returns true if after all events are
1069 performed it is still true. This sort of routine can be approximated
1070 by examining the DepCache, however in convoluted cases of provides
1071 this fails to produce a suitable result. */
1072 bool pkgOrderList::CheckDep(DepIterator D
)
1074 SPtrArray
<Version
*> List
= D
.AllTargets();
1076 for (Version
**I
= List
; *I
!= 0; I
++)
1078 VerIterator
Ver(Cache
,*I
);
1079 PkgIterator Pkg
= Ver
.ParentPkg();
1081 /* The meaning of Added and AddPending is subtle. AddPending is
1082 an indication that the package is looping. Because of the
1083 way ordering works Added means the package will be unpacked
1084 before this one and AddPending means after. It is therefore
1085 correct to ignore AddPending in all cases, but that exposes
1086 reverse-ordering loops which should be ignored. */
1087 if (IsFlag(Pkg
,Added
) == true ||
1088 (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true))
1090 if (Cache
[Pkg
].InstallVer
!= *I
)
1094 if ((Version
*)Pkg
.CurrentVer() != *I
||
1095 Pkg
.State() != PkgIterator::NeedsNothing
)
1098 /* Conflicts requires that all versions are not present, depends
1100 if (D
.IsNegative() == false)
1102 // ignore provides by older versions of this package
1103 if (((D
.Reverse() == false && Pkg
== D
.ParentPkg()) ||
1104 (D
.Reverse() == true && Pkg
== D
.TargetPkg())) &&
1105 Cache
[Pkg
].InstallVer
!= *I
)
1108 /* Try to find something that does not have the after flag set
1109 if at all possible */
1110 if (IsFlag(Pkg
,After
) == true)
1120 if (IsFlag(Pkg
,After
) == true)
1121 Flag(D
.ParentPkg(),After
);
1127 // We found a hit, but it had the after flag set
1128 if (Hit
== true && D
->Type
== pkgCache::Dep::PreDepends
)
1130 Flag(D
.ParentPkg(),After
);
1134 /* Conflicts requires that all versions are not present, depends
1136 if (D
->Type
== pkgCache::Dep::Conflicts
||
1137 D
->Type
== pkgCache::Dep::Obsoletes
)