]>
git.saurik.com Git - apt.git/blob - apt-pkg/orderlist.cc
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/sptr.h>
72 #include <apt-pkg/configuration.h>
73 #include <apt-pkg/cacheiterators.h>
74 #include <apt-pkg/pkgcache.h>
84 pkgOrderList
*pkgOrderList::Me
= 0;
86 // OrderList::pkgOrderList - Constructor /*{{{*/
87 // ---------------------------------------------------------------------
89 pkgOrderList::pkgOrderList(pkgDepCache
*pCache
) : Cache(*pCache
),
90 Primary(NULL
), Secondary(NULL
),
91 RevDepends(NULL
), Remove(NULL
),
92 AfterEnd(NULL
), FileList(NULL
),
93 LoopCount(-1), Depth(0)
95 Debug
= _config
->FindB("Debug::pkgOrderList",false);
97 /* Construct the arrays, egcs 1.0.1 bug requires the package count
99 unsigned long Size
= Cache
.Head().PackageCount
;
100 Flags
= new unsigned short[Size
];
101 End
= List
= new Package
*[Size
];
102 memset(Flags
,0,sizeof(*Flags
)*Size
);
105 // OrderList::~pkgOrderList - Destructor /*{{{*/
106 // ---------------------------------------------------------------------
108 pkgOrderList::~pkgOrderList()
114 // OrderList::IsMissing - Check if a file is missing /*{{{*/
115 // ---------------------------------------------------------------------
117 bool pkgOrderList::IsMissing(PkgIterator Pkg
)
119 // Skip packages to erase
120 if (Cache
[Pkg
].Delete() == true)
123 // Skip Packages that need configure only.
124 if ((Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
||
125 Pkg
.State() == pkgCache::PkgIterator::NeedsNothing
) &&
126 Cache
[Pkg
].Keep() == true)
132 if (FileList
[Pkg
->ID
].empty() == false)
138 // OrderList::DoRun - Does an order run /*{{{*/
139 // ---------------------------------------------------------------------
140 /* The caller is expeted to have setup the desired probe state */
141 bool pkgOrderList::DoRun()
144 unsigned long Size
= Cache
.Head().PackageCount
;
145 SPtrArray
<Package
*> NList
= new Package
*[Size
];
146 SPtrArray
<Package
*> AfterList
= new Package
*[Size
];
147 AfterEnd
= AfterList
;
150 WipeFlags(Added
| AddPending
| Loop
| InList
);
152 for (iterator I
= List
; I
!= End
; ++I
)
155 // Rebuild the main list into the temp list.
156 iterator OldEnd
= End
;
158 for (iterator I
= List
; I
!= OldEnd
; ++I
)
159 if (VisitNode(PkgIterator(Cache
,*I
), "DoRun") == false)
165 // Copy the after list to the end of the main list
166 for (Package
**I
= AfterList
; I
!= AfterEnd
; I
++)
169 // Swap the main list to the new list
171 List
= NList
.UnGuard();
175 // OrderList::OrderCritical - Perform critical unpacking ordering /*{{{*/
176 // ---------------------------------------------------------------------
177 /* This performs predepends and immediate configuration ordering only.
178 This is termed critical unpacking ordering. Any loops that form are
179 fatal and indicate that the packages cannot be installed. */
180 bool pkgOrderList::OrderCritical()
184 Primary
= &pkgOrderList::DepUnPackPreD
;
192 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareB
);
194 if (DoRun() == false)
198 return _error
->Error("Fatal, predepends looping detected");
202 clog
<< "** Critical Unpack ordering done" << endl
;
204 for (iterator I
= List
; I
!= End
; ++I
)
206 PkgIterator
P(Cache
,*I
);
207 if (IsNow(P
) == true)
208 clog
<< " " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
215 // OrderList::OrderUnpack - Perform complete unpacking ordering /*{{{*/
216 // ---------------------------------------------------------------------
217 /* This performs complete unpacking ordering and creates an order that is
218 suitable for unpacking */
219 bool pkgOrderList::OrderUnpack(string
*FileList
)
221 this->FileList
= FileList
;
223 // Setup the after flags
228 // Set the inlist flag
229 for (iterator I
= List
; I
!= End
; ++I
)
231 PkgIterator
P(Cache
,*I
);
232 if (IsMissing(P
) == true && IsNow(P
) == true)
237 Primary
= &pkgOrderList::DepUnPackCrit
;
238 Secondary
= &pkgOrderList::DepConfigure
;
239 RevDepends
= &pkgOrderList::DepUnPackDep
;
240 Remove
= &pkgOrderList::DepRemove
;
245 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareA
);
248 clog
<< "** Pass A" << endl
;
249 if (DoRun() == false)
253 clog
<< "** Pass B" << endl
;
255 if (DoRun() == false)
259 clog
<< "** Pass C" << endl
;
262 Remove
= 0; // Otherwise the libreadline remove problem occures
263 if (DoRun() == false)
267 clog
<< "** Pass D" << endl
;
269 Primary
= &pkgOrderList::DepUnPackPre
;
270 if (DoRun() == false)
275 clog
<< "** Unpack ordering done" << endl
;
277 for (iterator I
= List
; I
!= End
; ++I
)
279 PkgIterator
P(Cache
,*I
);
280 if (IsNow(P
) == true)
281 clog
<< " " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
288 // OrderList::OrderConfigure - Perform configuration ordering /*{{{*/
289 // ---------------------------------------------------------------------
290 /* This orders by depends only and produces an order which is suitable
292 bool pkgOrderList::OrderConfigure()
295 Primary
= &pkgOrderList::DepConfigure
;
303 // OrderList::Score - Score the package for sorting /*{{{*/
304 // ---------------------------------------------------------------------
305 /* Higher scores order earlier */
306 int pkgOrderList::Score(PkgIterator Pkg
)
308 // Removals should be done after we dealt with essentials
309 static int const ScoreDelete
= _config
->FindI("OrderList::Score::Delete", 100);
310 if (Cache
[Pkg
].Delete() == true)
313 // This should never happen..
314 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
317 static int const ScoreEssential
= _config
->FindI("OrderList::Score::Essential", 200);
318 static int const ScoreImmediate
= _config
->FindI("OrderList::Score::Immediate", 10);
319 static int const ScorePreDepends
= _config
->FindI("OrderList::Score::PreDepends", 50);
322 if ((Pkg
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
323 Score
+= ScoreEssential
;
325 if (IsFlag(Pkg
,Immediate
) == true)
326 Score
+= ScoreImmediate
;
328 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();
329 D
.end() == false; ++D
)
330 if (D
->Type
== pkgCache::Dep::PreDepends
)
332 Score
+= ScorePreDepends
;
336 // Important Required Standard Optional Extra
337 if (Cache
[Pkg
].InstVerIter(Cache
)->Priority
<= 5)
339 signed short PrioMap
[] = {0,5,4,3,1,0};
340 Score
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
];
345 // OrderList::FileCmp - Compare by package file /*{{{*/
346 // ---------------------------------------------------------------------
347 /* This compares by the package file that the install version is in. */
348 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
)
350 if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true)
352 if (Cache
[A
].Delete() == true)
354 if (Cache
[B
].Delete() == true)
357 if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true)
359 if (Cache
[B
].InstVerIter(Cache
).FileList().end() == true)
362 pkgCache::PackageFile
*FA
= Cache
[A
].InstVerIter(Cache
).FileList().File();
363 pkgCache::PackageFile
*FB
= Cache
[B
].InstVerIter(Cache
).FileList().File();
371 // BoolCompare - Comparison function for two booleans /*{{{*/
372 // ---------------------------------------------------------------------
374 static int BoolCompare(bool A
,bool B
)
383 // OrderList::OrderCompareA - Order the installation by op /*{{{*/
384 // ---------------------------------------------------------------------
385 /* This provides a first-pass sort of the list and gives a decent starting
386 point for further complete ordering. It is used by OrderUnpack only */
387 int pkgOrderList::OrderCompareA(const void *a
, const void *b
)
389 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
390 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
392 // We order packages with a set state toward the front
394 if ((Res
= BoolCompare(Me
->IsNow(A
),Me
->IsNow(B
))) != 0)
397 // We order missing files to toward the end
398 /* if (Me->FileList != 0)
400 if ((Res = BoolCompare(Me->IsMissing(A),
401 Me->IsMissing(B))) != 0)
405 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
406 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
409 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
410 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
413 int ScoreA
= Me
->Score(A
);
414 int ScoreB
= Me
->Score(B
);
422 return strcmp(A
.Name(),B
.Name());
425 // OrderList::OrderCompareB - Order the installation by source /*{{{*/
426 // ---------------------------------------------------------------------
427 /* This orders by installation source. This is useful to handle
428 inter-source breaks */
429 int pkgOrderList::OrderCompareB(const void *a
, const void *b
)
431 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
432 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
434 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
435 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
438 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
439 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
442 int F
= Me
->FileCmp(A
,B
);
450 int ScoreA
= Me
->Score(A
);
451 int ScoreB
= Me
->Score(B
);
459 return strcmp(A
.Name(),B
.Name());
462 // OrderList::VisitDeps - Visit forward install dependencies /*{{{*/
463 // ---------------------------------------------------------------------
464 /* This calls the dependency function for the normal forwards dependencies
466 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
)
468 if (F
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer
== 0)
471 return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList());
474 // OrderList::VisitRDeps - Visit reverse dependencies /*{{{*/
475 // ---------------------------------------------------------------------
476 /* This calls the dependency function for all of the normal reverse depends
478 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
)
480 if (F
== 0 || Pkg
.end() == true)
483 return (this->*F
)(Pkg
.RevDependsList());
486 // OrderList::VisitRProvides - Visit provides reverse dependencies /*{{{*/
487 // ---------------------------------------------------------------------
488 /* This calls the dependency function for all reverse dependencies
489 generated by the provides line on the package. */
490 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
)
492 if (F
== 0 || Ver
.end() == true)
496 for (PrvIterator P
= Ver
.ProvidesList(); P
.end() == false; ++P
)
497 Res
&= (this->*F
)(P
.ParentPkg().RevDependsList());
501 // OrderList::VisitProvides - Visit all of the providing packages /*{{{*/
502 // ---------------------------------------------------------------------
503 /* This routine calls visit on all providing packages.
505 If the dependency is negative it first visits packages which are
506 intended to be removed and after that all other packages.
507 It does so to avoid situations in which this package is used to
508 satisfy a (or-group/provides) dependency of another package which
509 could have been satisfied also by upgrading another package -
510 otherwise we have more broken packages dpkg needs to auto-
511 deconfigure and in very complicated situations it even decides
513 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
)
515 SPtrArray
<Version
*> List
= D
.AllTargets();
516 for (Version
**I
= List
; *I
!= 0; ++I
)
518 VerIterator
Ver(Cache
,*I
);
519 PkgIterator Pkg
= Ver
.ParentPkg();
521 if (D
.IsNegative() == true && Cache
[Pkg
].Delete() == false)
524 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
527 if (D
.IsNegative() == false &&
528 Cache
[Pkg
].InstallVer
!= *I
)
531 if (D
.IsNegative() == true &&
532 (Version
*)Pkg
.CurrentVer() != *I
)
535 // Skip over missing files
536 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
539 if (VisitNode(Pkg
, "Provides-1") == false)
542 if (D
.IsNegative() == false)
544 for (Version
**I
= List
; *I
!= 0; ++I
)
546 VerIterator
Ver(Cache
,*I
);
547 PkgIterator Pkg
= Ver
.ParentPkg();
549 if (Cache
[Pkg
].Delete() == true)
552 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
555 if ((Version
*)Pkg
.CurrentVer() != *I
)
558 // Skip over missing files
559 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
562 if (VisitNode(Pkg
, "Provides-2") == false)
569 // OrderList::VisitNode - Recursive ordering director /*{{{*/
570 // ---------------------------------------------------------------------
571 /* This is the core ordering routine. It calls the set dependency
572 consideration functions which then potentialy call this again. Finite
573 depth is achieved through the colouring mechinism. */
574 bool pkgOrderList::VisitNode(PkgIterator Pkg
, char const* from
)
576 // Looping or irrelevant.
577 // This should probably trancend not installed packages
578 if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||
579 IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false)
584 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
585 clog
<< "Visit " << Pkg
.FullName() << " from " << from
<< endl
;
591 Flag(Pkg
,AddPending
);
593 DepFunc Old
= Primary
;
595 // Perform immedate configuration of the package if so flagged.
596 if (IsFlag(Pkg
,Immediate
) == true && Primary
!= &pkgOrderList::DepUnPackPre
)
597 Primary
= &pkgOrderList::DepUnPackPreD
;
599 if (IsNow(Pkg
) == true)
602 if (Cache
[Pkg
].Delete() == false)
605 Res
&= Res
&& VisitDeps(Primary
,Pkg
);
606 Res
&= Res
&& VisitRDeps(Primary
,Pkg
);
607 Res
&= Res
&& VisitRProvides(Primary
,Pkg
.CurrentVer());
608 Res
&= Res
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
));
611 Res
&= Res
&& VisitRDeps(RevDepends
,Pkg
);
612 Res
&= Res
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer());
613 Res
&= Res
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
));
616 Res
&= Res
&& VisitDeps(Secondary
,Pkg
);
617 Res
&= Res
&& VisitRDeps(Secondary
,Pkg
);
618 Res
&= Res
&& VisitRProvides(Secondary
,Pkg
.CurrentVer());
619 Res
&= Res
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
));
624 Res
&= Res
&& VisitRDeps(Remove
,Pkg
);
625 Res
&= Res
&& VisitRProvides(Remove
,Pkg
.CurrentVer());
629 if (IsFlag(Pkg
,Added
) == false)
631 Flag(Pkg
,Added
,Added
| AddPending
);
632 if (IsFlag(Pkg
,After
) == true)
643 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
644 clog
<< "Leave " << Pkg
.FullName() << ' ' << IsFlag(Pkg
,Added
) << ',' << IsFlag(Pkg
,AddPending
) << endl
;
650 // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
651 // ---------------------------------------------------------------------
652 /* Critical unpacking ordering strives to satisfy Conflicts: and
653 PreDepends: only. When a prdepends is encountered the Primary
654 DepFunc is changed to be DepUnPackPreD.
656 Loops are preprocessed and logged. */
657 bool pkgOrderList::DepUnPackCrit(DepIterator D
)
659 for (; D
.end() == false; ++D
)
661 if (D
.Reverse() == true)
663 /* Reverse depenanices are only interested in conflicts,
664 predepend breakage is ignored here */
665 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
666 D
->Type
!= pkgCache::Dep::Obsoletes
)
669 // Duplication elimination, consider only the current version
670 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
673 /* For reverse dependencies we wish to check if the
674 dependency is satisifed in the install state. The
675 target package (caller) is going to be in the installed
677 if (CheckDep(D
) == true)
680 if (VisitNode(D
.ParentPkg(), "UnPackCrit") == false)
685 /* Forward critical dependencies MUST be correct before the
686 package can be unpacked. */
687 if (D
.IsNegative() == false &&
688 D
->Type
!= pkgCache::Dep::PreDepends
)
691 /* We wish to check if the dep is okay in the now state of the
692 target package against the install state of this package. */
693 if (CheckDep(D
) == true)
695 /* We want to catch predepends loops with the code below.
696 Conflicts loops that are Dep OK are ignored */
697 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
698 D
->Type
!= pkgCache::Dep::PreDepends
)
702 // This is the loop detection
703 if (IsFlag(D
.TargetPkg(),Added
) == true ||
704 IsFlag(D
.TargetPkg(),AddPending
) == true)
706 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
711 /* Predepends require a special ordering stage, they must have
712 all dependents installed as well */
713 DepFunc Old
= Primary
;
715 if (D
->Type
== pkgCache::Dep::PreDepends
)
716 Primary
= &pkgOrderList::DepUnPackPreD
;
717 Res
= VisitProvides(D
,true);
726 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
727 // ---------------------------------------------------------------------
728 /* Critical PreDepends (also configure immediate and essential) strives to
729 ensure not only that all conflicts+predepends are met but that this
730 package will be immediately configurable when it is unpacked.
731 Loops are preprocessed and logged. */
732 bool pkgOrderList::DepUnPackPreD(DepIterator D
)
734 if (D
.Reverse() == true)
735 return DepUnPackCrit(D
);
737 for (; D
.end() == false; ++D
)
739 if (D
.IsCritical() == false)
742 /* We wish to check if the dep is okay in the now state of the
743 target package against the install state of this package. */
744 if (CheckDep(D
) == true)
746 /* We want to catch predepends loops with the code below.
747 Conflicts loops that are Dep OK are ignored */
748 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
749 D
->Type
!= pkgCache::Dep::PreDepends
)
753 // This is the loop detection
754 if (IsFlag(D
.TargetPkg(),Added
) == true ||
755 IsFlag(D
.TargetPkg(),AddPending
) == true)
757 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
762 if (VisitProvides(D
,true) == false)
768 // OrderList::DepUnPackPre - Critical Predepends ordering /*{{{*/
769 // ---------------------------------------------------------------------
770 /* Critical PreDepends (also configure immediate and essential) strives to
771 ensure not only that all conflicts+predepends are met but that this
772 package will be immediately configurable when it is unpacked.
774 Loops are preprocessed and logged. All loops will be fatal. */
775 bool pkgOrderList::DepUnPackPre(DepIterator D
)
777 if (D
.Reverse() == true)
780 for (; D
.end() == false; ++D
)
782 /* Only consider the PreDepends or Depends. Depends are only
783 considered at the lowest depth or in the case of immediate
785 if (D
->Type
!= pkgCache::Dep::PreDepends
)
787 if (D
->Type
== pkgCache::Dep::Depends
)
789 if (Depth
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false)
796 /* We wish to check if the dep is okay in the now state of the
797 target package against the install state of this package. */
798 if (CheckDep(D
) == true)
800 /* We want to catch predepends loops with the code below.
801 Conflicts loops that are Dep OK are ignored */
802 if (IsFlag(D
.TargetPkg(),AddPending
) == false)
806 // This is the loop detection
807 if (IsFlag(D
.TargetPkg(),Added
) == true ||
808 IsFlag(D
.TargetPkg(),AddPending
) == true)
810 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
815 if (VisitProvides(D
,true) == false)
821 // OrderList::DepUnPackDep - Reverse dependency considerations /*{{{*/
822 // ---------------------------------------------------------------------
823 /* Reverse dependencies are considered to determine if unpacking this
824 package will break any existing dependencies. If so then those
825 packages are ordered before this one so that they are in the
828 The forwards depends loop is designed to bring the packages dependents
829 close to the package. This helps reduce deconfigure time.
831 Loops are irrelevant to this. */
832 bool pkgOrderList::DepUnPackDep(DepIterator D
)
835 for (; D
.end() == false; ++D
)
836 if (D
.IsCritical() == true)
838 if (D
.Reverse() == true)
840 /* Duplication prevention. We consider rev deps only on
841 the current version, a not installed package
843 if (D
.ParentPkg()->CurrentVer
== 0 ||
844 D
.ParentPkg().CurrentVer() != D
.ParentVer())
847 // The dep will not break so it is irrelevant.
848 if (CheckDep(D
) == true)
851 // Skip over missing files
852 if (IsMissing(D
.ParentPkg()) == true)
855 if (VisitNode(D
.ParentPkg(), "UnPackDep-Parent") == false)
860 if (D
->Type
== pkgCache::Dep::Depends
)
861 if (VisitProvides(D
,false) == false)
864 if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
866 if (CheckDep(D
) == true)
869 if (VisitNode(D
.TargetPkg(), "UnPackDep-Target") == false)
877 // OrderList::DepConfigure - Configuration ordering /*{{{*/
878 // ---------------------------------------------------------------------
879 /* Configuration only ordering orders by the Depends: line only. It
880 orders configuration so that when a package comes to be configured it's
881 dependents are configured.
883 Loops are ingored. Depends loop entry points are chaotic. */
884 bool pkgOrderList::DepConfigure(DepIterator D
)
886 // Never consider reverse configuration dependencies.
887 if (D
.Reverse() == true)
890 for (; D
.end() == false; ++D
)
891 if (D
->Type
== pkgCache::Dep::Depends
)
892 if (VisitProvides(D
,false) == false)
897 // OrderList::DepRemove - Removal ordering /*{{{*/
898 // ---------------------------------------------------------------------
899 /* Checks all given dependencies if they are broken by the remove of a
900 package and if so fix it by visiting another provider or or-group
901 member to ensure that the dependee keeps working which is especially
902 important for Immediate packages like e.g. those depending on an
903 awk implementation. If the dependency can't be fixed with another
904 package this means an upgrade of the package will solve the problem. */
905 bool pkgOrderList::DepRemove(DepIterator Broken
)
907 if (Broken
.Reverse() == false)
910 for (; Broken
.end() == false; ++Broken
)
912 if (Broken
->Type
!= pkgCache::Dep::Depends
&&
913 Broken
->Type
!= pkgCache::Dep::PreDepends
)
916 PkgIterator BrokenPkg
= Broken
.ParentPkg();
917 // uninstalled packages can't break via a remove
918 if (BrokenPkg
->CurrentVer
== 0)
921 // if its already added, we can't do anything useful
922 if (IsFlag(BrokenPkg
, AddPending
) == true || IsFlag(BrokenPkg
, Added
) == true)
925 // if the dependee is going to be removed, visit it now
926 if (Cache
[BrokenPkg
].Delete() == true)
927 return VisitNode(BrokenPkg
, "Remove-Dependee");
929 // The package stays around, so find out how this is possible
930 for (DepIterator D
= BrokenPkg
.CurrentVer().DependsList(); D
.end() == false;)
932 // only important or-groups need fixing
933 if (D
->Type
!= pkgCache::Dep::Depends
&&
934 D
->Type
!= pkgCache::Dep::PreDepends
)
940 // Start is the beginning of the or-group, D is the first one after or
941 DepIterator Start
= D
;
942 bool foundBroken
= false;
943 for (bool LastOR
= true; D
.end() == false && LastOR
== true; ++D
)
945 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
950 // this or-group isn't the broken one: keep searching
951 if (foundBroken
== false)
954 // iterate over all members of the or-group searching for a ready replacement
955 bool readyReplacement
= false;
956 for (DepIterator OrMember
= Start
; OrMember
!= D
&& readyReplacement
== false; ++OrMember
)
958 Version
** Replacements
= OrMember
.AllTargets();
959 for (Version
**R
= Replacements
; *R
!= 0; ++R
)
961 VerIterator
Ver(Cache
,*R
);
962 // only currently installed packages can be a replacement
963 PkgIterator RPkg
= Ver
.ParentPkg();
964 if (RPkg
.CurrentVer() != Ver
)
967 // packages going to be removed can't be a replacement
968 if (Cache
[RPkg
].Delete() == true)
971 readyReplacement
= true;
974 delete[] Replacements
;
977 // something else is ready to take over, do nothing
978 if (readyReplacement
== true)
981 // see if we can visit a replacement
982 bool visitReplacement
= false;
983 for (DepIterator OrMember
= Start
; OrMember
!= D
&& visitReplacement
== false; ++OrMember
)
985 Version
** Replacements
= OrMember
.AllTargets();
986 for (Version
**R
= Replacements
; *R
!= 0; ++R
)
988 VerIterator
Ver(Cache
,*R
);
989 // consider only versions we plan to install
990 PkgIterator RPkg
= Ver
.ParentPkg();
991 if (Cache
[RPkg
].Install() == false || Cache
[RPkg
].InstallVer
!= Ver
)
994 // loops are not going to help us, so don't create them
995 if (IsFlag(RPkg
, AddPending
) == true)
998 if (IsMissing(RPkg
) == true)
1001 visitReplacement
= true;
1002 if (IsFlag(BrokenPkg
, Immediate
) == false)
1004 if (VisitNode(RPkg
, "Remove-Rep") == true)
1009 Flag(RPkg
, Immediate
);
1010 if (VisitNode(RPkg
, "Remove-ImmRep") == true)
1013 visitReplacement
= false;
1015 delete[] Replacements
;
1017 if (visitReplacement
== true)
1020 // the broken package in current version can't be fixed, so install new version
1021 if (IsMissing(BrokenPkg
) == true)
1024 if (VisitNode(BrokenPkg
, "Remove-Upgrade") == false)
1032 // OrderList::AddLoop - Add a loop to the loop list /*{{{*/
1033 // ---------------------------------------------------------------------
1034 /* We record the loops. This is a relic since loop breaking is done
1035 genericaly as part of the safety routines. */
1036 bool pkgOrderList::AddLoop(DepIterator D
)
1038 if (LoopCount
< 0 || LoopCount
>= 20)
1044 if (Loops
[LoopCount
- 1].ParentPkg() == D
.ParentPkg() ||
1045 Loops
[LoopCount
- 1].TargetPkg() == D
.ParentPkg())
1049 Loops
[LoopCount
++] = D
;
1051 // Mark the packages as being part of a loop.
1052 //Flag(D.TargetPkg(),Loop);
1053 //Flag(D.ParentPkg(),Loop);
1054 /* This is currently disabled because the Loop flag is being used for
1055 loop management in the package manager. Check the orderlist.h file for more info */
1059 // OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/
1060 // ---------------------------------------------------------------------
1062 void pkgOrderList::WipeFlags(unsigned long F
)
1064 unsigned long Size
= Cache
.Head().PackageCount
;
1065 for (unsigned long I
= 0; I
!= Size
; I
++)
1069 // OrderList::CheckDep - Check a dependency for truth /*{{{*/
1070 // ---------------------------------------------------------------------
1071 /* This performs a complete analysis of the dependency wrt to the
1072 current add list. It returns true if after all events are
1073 performed it is still true. This sort of routine can be approximated
1074 by examining the DepCache, however in convoluted cases of provides
1075 this fails to produce a suitable result. */
1076 bool pkgOrderList::CheckDep(DepIterator D
)
1078 SPtrArray
<Version
*> List
= D
.AllTargets();
1080 for (Version
**I
= List
; *I
!= 0; I
++)
1082 VerIterator
Ver(Cache
,*I
);
1083 PkgIterator Pkg
= Ver
.ParentPkg();
1085 /* The meaning of Added and AddPending is subtle. AddPending is
1086 an indication that the package is looping. Because of the
1087 way ordering works Added means the package will be unpacked
1088 before this one and AddPending means after. It is therefore
1089 correct to ignore AddPending in all cases, but that exposes
1090 reverse-ordering loops which should be ignored. */
1091 if (IsFlag(Pkg
,Added
) == true ||
1092 (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true))
1094 if (Cache
[Pkg
].InstallVer
!= *I
)
1098 if ((Version
*)Pkg
.CurrentVer() != *I
||
1099 Pkg
.State() != PkgIterator::NeedsNothing
)
1102 /* Conflicts requires that all versions are not present, depends
1104 if (D
.IsNegative() == false)
1106 // ignore provides by older versions of this package
1107 if (((D
.Reverse() == false && Pkg
== D
.ParentPkg()) ||
1108 (D
.Reverse() == true && Pkg
== D
.TargetPkg())) &&
1109 Cache
[Pkg
].InstallVer
!= *I
)
1112 /* Try to find something that does not have the after flag set
1113 if at all possible */
1114 if (IsFlag(Pkg
,After
) == true)
1124 if (IsFlag(Pkg
,After
) == true)
1125 Flag(D
.ParentPkg(),After
);
1131 // We found a hit, but it had the after flag set
1132 if (Hit
== true && D
->Type
== pkgCache::Dep::PreDepends
)
1134 Flag(D
.ParentPkg(),After
);
1138 /* Conflicts requires that all versions are not present, depends
1140 if (D
->Type
== pkgCache::Dep::Conflicts
||
1141 D
->Type
== pkgCache::Dep::Obsoletes
)