]>
git.saurik.com Git - apt.git/blob - apt-pkg/depcache.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: depcache.cc,v 1.13 1998/12/22 07:58:50 jgg Exp $
4 /* ######################################################################
6 Dependency Cache - Caches Dependency information.
8 ##################################################################### */
10 // Include Files /*{{{*/
12 #pragma implementation "apt-pkg/depcache.h"
14 #include <apt-pkg/depcache.h>
15 #include <apt-pkg/configuration.h>
17 #include <apt-pkg/version.h>
18 #include <apt-pkg/error.h>
21 // DepCache::pkgDepCache - Constructors /*{{{*/
22 // ---------------------------------------------------------------------
24 pkgDepCache::pkgDepCache(MMap
&Map
,OpProgress
&Prog
) :
25 pkgCache(Map
), PkgState(0), DepState(0)
27 if (_error
->PendingError() == false)
30 pkgDepCache::pkgDepCache(MMap
&Map
) :
31 pkgCache(Map
), PkgState(0), DepState(0)
33 if (_error
->PendingError() == false)
37 // DepCache::~pkgDepCache - Destructor /*{{{*/
38 // ---------------------------------------------------------------------
40 pkgDepCache::~pkgDepCache()
46 // DepCache::Init - Generate the initial extra structures. /*{{{*/
47 // ---------------------------------------------------------------------
48 /* This allocats the extension buffers and initializes them. */
49 bool pkgDepCache::Init(OpProgress
*Prog
)
53 PkgState
= new StateCache
[Head().PackageCount
];
54 DepState
= new unsigned char[Head().DependsCount
];
55 memset(PkgState
,0,sizeof(*PkgState
)*Head().PackageCount
);
56 memset(DepState
,0,sizeof(*DepState
)*Head().DependsCount
);
60 Prog
->OverallProgress(0,2*Head().PackageCount
,Head().PackageCount
,
61 "Building Dependency Tree");
62 Prog
->SubProgress(Head().PackageCount
,"Candidate Versions");
65 /* Set the current state of everything. In this state all of the
66 packages are kept exactly as is. See AllUpgrade */
68 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
73 // Find the proper cache slot
74 StateCache
&State
= PkgState
[I
->ID
];
77 // Figure out the install version
78 State
.CandidateVer
= GetCandidateVer(I
);
79 State
.InstallVer
= I
.CurrentVer();
80 State
.Mode
= ModeKeep
;
82 State
.Update(I
,*this);
88 Prog
->OverallProgress(Head().PackageCount
,2*Head().PackageCount
,
90 "Building Dependency Tree");
91 Prog
->SubProgress(Head().PackageCount
,"Dependency Generation");
99 // DepCache::GetCandidateVer - Returns the Candidate install version /*{{{*/
100 // ---------------------------------------------------------------------
101 /* The default just returns the target version if it exists or the
103 pkgDepCache::VerIterator
pkgDepCache::GetCandidateVer(PkgIterator Pkg
)
105 // Try to use an explicit target
106 if (Pkg
->TargetVer
== 0)
108 string DistHack
= _config
->Find("to");
110 /* If disthack is set then we look for a dist by that name to install
112 if (DistHack
.empty() == false)
114 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
116 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
117 if ((J
.File()->Flags
& Flag::NotSource
) == 0 &&
118 (J
.File()->Flags
& Flag::NotAutomatic
) == 0 &&
119 J
.File().Archive() == DistHack
)
123 // Hmm, target is current if there is no alternative.
124 if (Pkg
->CurrentVer
!= 0)
125 return Pkg
.CurrentVer();
129 /* Not source/not automatic versions cannot be a candidate version
130 unless they are already installed */
131 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
133 if (Pkg
.CurrentVer() == I
)
135 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
136 if ((J
.File()->Flags
& Flag::NotSource
) == 0 &&
137 (J
.File()->Flags
& Flag::NotAutomatic
) == 0)
142 return VerIterator(*this,0);
145 return Pkg
.TargetVer();
148 // DepCache::IsImportantDep - True if the dependency is important /*{{{*/
149 // ---------------------------------------------------------------------
151 bool pkgDepCache::IsImportantDep(DepIterator Dep
)
153 return Dep
.IsCritical();
157 // DepCache::CheckDep - Checks a single dependency /*{{{*/
158 // ---------------------------------------------------------------------
159 /* This first checks the dependency against the main target package and
160 then walks along the package provides list and checks if each provides
161 will be installed then checks the provides against the dep. Res will be
162 set to the package which was used to satisfy the dep. */
163 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
165 Res
= Dep
.TargetPkg();
167 /* Check simple depends. A depends -should- never self match but
168 we allow it anyhow because dpkg does. Technically it is a packaging
169 bug. Conflicts may never self match */
170 if (Dep
.TargetPkg() != Dep
.ParentPkg() || Dep
->Type
!= Dep::Conflicts
)
172 PkgIterator Pkg
= Dep
.TargetPkg();
173 // Check the base package
174 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
175 if (pkgCheckDep(Dep
.TargetVer(),
176 Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
) == true)
179 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
180 if (pkgCheckDep(Dep
.TargetVer(),
181 PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
182 Dep
->CompareOp
) == true)
185 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
186 if (pkgCheckDep(Dep
.TargetVer(),
187 PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
188 Dep
->CompareOp
) == true)
192 // Check the providing packages
193 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
194 PkgIterator Pkg
= Dep
.ParentPkg();
195 for (; P
.end() != true; P
++)
197 /* Provides may never be applied against the same package if it is
198 a conflicts. See the comment above. */
199 if (P
.OwnerPkg() == Pkg
&& Dep
->Type
== Dep::Conflicts
)
202 // Check if the provides is a hit
203 if (Type
== NowVersion
)
205 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
209 if (Type
== InstallVersion
)
211 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
212 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
216 if (Type
== CandidateVersion
)
218 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
219 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
223 // Compare the versions.
224 if (pkgCheckDep(Dep
.TargetVer(),P
.ProvideVersion(),Dep
->CompareOp
) == true)
234 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
235 // ---------------------------------------------------------------------
236 /* Call with Mult = -1 to preform the inverse opration */
237 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,long Mult
)
239 StateCache
&P
= PkgState
[Pkg
->ID
];
241 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
)
243 iUsrSize
+= Mult
*P
.InstVerIter(*this)->InstalledSize
;
247 // Compute the size data
248 if (P
.NewInstall() == true)
250 iUsrSize
+= Mult
*P
.InstVerIter(*this)->InstalledSize
;
251 iDownloadSize
+= Mult
*P
.InstVerIter(*this)->Size
;
256 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() &&
259 iUsrSize
+= Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
260 (signed)Pkg
.CurrentVer()->InstalledSize
);
261 iDownloadSize
+= Mult
*P
.InstVerIter(*this)->Size
;
266 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
269 iDownloadSize
+= Mult
*P
.InstVerIter(*this)->Size
;
274 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
276 iUsrSize
-= Mult
*Pkg
.CurrentVer()->InstalledSize
;
281 // DepCache::AddStates - Add the package to the state counter /*{{{*/
282 // ---------------------------------------------------------------------
283 /* This routine is tricky to use, you must make sure that it is never
284 called twice for the same package. This means the Remove/Add section
285 should be as short as possible and not encompass any code that will
286 calld Remove/Add itself. Remember, dependencies can be circular so
287 while processing a dep for Pkg it is possible that Add/Remove
288 will be called on Pkg */
289 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
291 StateCache
&State
= PkgState
[Pkg
->ID
];
293 // The Package is broken
294 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
298 if (Pkg
.State() != PkgIterator::NeedsNothing
)
302 if (Pkg
->CurrentVer
== 0)
304 if (State
.Mode
== ModeInstall
)
309 // Installed, no upgrade
310 if (State
.Upgradable() == false)
312 if (State
.Mode
== ModeDelete
)
314 if (State
.Mode
== ModeInstall
)
319 // Alll 3 are possible
320 if (State
.Mode
== ModeDelete
)
322 if (State
.Mode
== ModeKeep
)
324 if (State
.Mode
== ModeInstall
)
328 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
329 // ---------------------------------------------------------------------
330 /* The or group results are stored in the last item of the or group. This
331 allows easy detection of the state of a whole or'd group. */
332 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
334 unsigned char Group
= 0;
336 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
338 // Build the dependency state.
339 unsigned char &State
= DepState
[D
->ID
];
341 /* Invert for Conflicts. We have to do this twice to get the
342 right sense for a conflicts group */
343 if (D
->Type
== Dep::Conflicts
)
346 // Add to the group if we are within an or..
350 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
353 // Invert for Conflicts
354 if (D
->Type
== Dep::Conflicts
)
359 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
360 // ---------------------------------------------------------------------
361 /* This is used to run over a dependency list and determine the dep
362 state of the list, filtering it through both a Min check and a Policy
363 check. The return result will have SetMin/SetPolicy low if a check
364 fails. It uses the DepState cache for it's computations. */
365 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
366 unsigned char SetMin
,
367 unsigned char SetPolicy
)
369 unsigned char Dep
= 0xFF;
371 while (D
.end() != true)
373 // Compute a single dependency element (glob or)
374 DepIterator Start
= D
;
375 unsigned char State
= 0;
376 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
378 State
|= DepState
[D
->ID
];
379 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
382 // Minimum deps that must be satisfied to have a working package
383 if (Start
.IsCritical() == true)
384 if ((State
& Check
) != Check
)
387 // Policy deps that must be satisfied to install the package
388 if (IsImportantDep(Start
) == true &&
389 (State
& Check
) != Check
)
396 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
397 // ---------------------------------------------------------------------
398 /* This is the main dependency computation bit. It computes the 3 main
399 results for a dependencys, Now, Install and Candidate. Callers must
400 invert the result if dealing with conflicts. */
401 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
403 unsigned char State
= 0;
405 if (CheckDep(D
,NowVersion
) == true)
407 if (CheckDep(D
,InstallVersion
) == true)
409 if (CheckDep(D
,CandidateVersion
) == true)
415 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
416 // ---------------------------------------------------------------------
417 /* This determines the combined dependency representation of a package
418 for its two states now and install. This is done by using the pre-generated
419 dependency information. */
420 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
422 // Empty deps are always true
423 StateCache
&State
= PkgState
[Pkg
->ID
];
424 State
.DepState
= 0xFF;
426 // Check the Current state
427 if (Pkg
->CurrentVer
!= 0)
429 DepIterator D
= Pkg
.CurrentVer().DependsList();
430 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
433 /* Check the candidate state. We do not compare against the whole as
434 a candidate state but check the candidate version against the
436 if (State
.CandidateVer
!= 0)
438 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
439 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
442 // Check target state which can only be current or installed
443 if (State
.InstallVer
!= 0)
445 DepIterator D
= State
.InstVerIter(*this).DependsList();
446 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
450 // DepCache::Update - Figure out all the state information /*{{{*/
451 // ---------------------------------------------------------------------
452 /* This will figure out the state of all the packages and all the
453 dependencies based on the current policy. */
454 void pkgDepCache::Update(OpProgress
*Prog
)
464 // Perform the depends pass
466 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
468 if (Prog
!= 0 && Done%20
== 0)
469 Prog
->Progress(Done
);
470 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
472 unsigned char Group
= 0;
474 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
476 // Build the dependency state.
477 unsigned char &State
= DepState
[D
->ID
];
478 State
= DependencyState(D
);;
480 // Add to the group if we are within an or..
483 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
486 // Invert for Conflicts
487 if (D
->Type
== Dep::Conflicts
)
492 // Compute the pacakge dependency state and size additions
499 Prog
->Progress(Done
);
502 // DepCache::Update - Update the deps list of a package /*{{{*/
503 // ---------------------------------------------------------------------
504 /* This is a helper for update that only does the dep portion of the scan.
505 It is mainly ment to scan reverse dependencies. */
506 void pkgDepCache::Update(DepIterator D
)
508 // Update the reverse deps
509 for (;D
.end() != true; D
++)
511 unsigned char &State
= DepState
[D
->ID
];
512 State
= DependencyState(D
);
514 // Invert for Conflicts
515 if (D
->Type
== Dep::Conflicts
)
518 RemoveStates(D
.ParentPkg());
519 BuildGroupOrs(D
.ParentVer());
520 UpdateVerState(D
.ParentPkg());
521 AddStates(D
.ParentPkg());
525 // DepCache::Update - Update the related deps of a package /*{{{*/
526 // ---------------------------------------------------------------------
527 /* This is called whenever the state of a package changes. It updates
528 all cached dependencies related to this package. */
529 void pkgDepCache::Update(PkgIterator
const &Pkg
)
531 // Recompute the dep of the package
536 // Update the reverse deps
537 Update(Pkg
.RevDependsList());
539 // Update the provides map for the current ver
540 if (Pkg
->CurrentVer
!= 0)
541 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
542 P
.end() != true; P
++)
543 Update(P
.ParentPkg().RevDependsList());
545 // Update the provides map for the candidate ver
546 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
547 P
.end() != true; P
++)
548 Update(P
.ParentPkg().RevDependsList());
553 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
554 // ---------------------------------------------------------------------
556 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
,bool Soft
)
558 // Simplifies other routines.
559 if (Pkg
.end() == true)
562 /* We changed the soft state all the time so the UI is a bit nicer
564 StateCache
&P
= PkgState
[Pkg
->ID
];
566 P
.iFlags
|= AutoKept
;
568 P
.iFlags
&= ~AutoKept
;
570 // Check that it is not already kept
571 if (P
.Mode
== ModeKeep
)
574 // We dont even try to keep virtual packages..
575 if (Pkg
->VersionList
== 0)
578 P
.Flags
&= ~Flag::Auto
;
583 if (Pkg
->CurrentVer
== 0)
586 P
.InstallVer
= Pkg
.CurrentVer();
595 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
596 // ---------------------------------------------------------------------
598 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
)
600 // Simplifies other routines.
601 if (Pkg
.end() == true)
604 // Check that it is not already marked for delete
605 StateCache
&P
= PkgState
[Pkg
->ID
];
606 P
.iFlags
&= ~AutoKept
;
607 if (P
.Mode
== ModeDelete
|| P
.InstallVer
== 0)
610 // We dont even try to delete virtual packages..
611 if (Pkg
->VersionList
== 0)
617 if (Pkg
->CurrentVer
== 0)
622 P
.Flags
&= Flag::Auto
;
629 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
630 // ---------------------------------------------------------------------
632 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
)
634 // Simplifies other routines.
635 if (Pkg
.end() == true)
638 /* Check that it is not already marked for install and that it can be
640 StateCache
&P
= PkgState
[Pkg
->ID
];
641 P
.iFlags
&= ~AutoKept
;
642 if (P
.InstBroken() == false && (P
.Mode
== ModeInstall
||
643 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
645 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
650 // We dont even try to install virtual packages..
651 if (Pkg
->VersionList
== 0)
654 /* Target the candidate version and remove the autoflag. We reset the
655 autoflag below if this was called recursively. Otherwise the user
656 should have the ability to de-auto a package by changing its state */
660 P
.Mode
= ModeInstall
;
661 P
.InstallVer
= P
.CandidateVer
;
662 P
.Flags
&= ~Flag::Auto
;
663 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
670 if (AutoInst
== false)
673 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
674 for (; Dep
.end() != true;)
677 DepIterator Start
= Dep
;
679 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++)
681 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
683 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
687 // Dep is satisfied okay.
691 /* Check if this dep should be consider for install. If it is a user
692 defined important dep and we are installed a new package then
693 it will be installed. Otherwise we only worry about critical deps */
694 if (IsImportantDep(Start
) == false)
696 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false)
699 // Now we have to take action...
700 PkgIterator P
= Start
.SmartTargetPkg();
701 if ((DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
705 // Set the autoflag, after MarkInstall because MarkInstall unsets it
706 if (P
->CurrentVer
== 0)
707 PkgState
[P
->ID
].Flags
|= Flag::Auto
;
712 // For conflicts we just de-install the package and mark as auto
713 if (Start
->Type
== Dep::Conflicts
)
715 Version
**List
= Start
.AllTargets();
716 for (Version
**I
= List
; *I
!= 0; I
++)
718 VerIterator
Ver(*this,*I
);
719 PkgIterator Pkg
= Ver
.ParentPkg();
722 PkgState
[Pkg
->ID
].Flags
|= Flag::Auto
;
731 // StateCache::Update - Compute the various static display things /*{{{*/
732 // ---------------------------------------------------------------------
733 /* This is called whenever the Candidate version changes. */
734 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
737 VerIterator Ver
= CandidateVerIter(Cache
);
739 // Use a null string or the version string
740 if (Ver
.end() == true)
743 CandVersion
= Ver
.VerStr();
745 // Find the current version
747 if (Pkg
->CurrentVer
!= 0)
748 CurVersion
= Pkg
.CurrentVer().VerStr();
750 // Strip off the epochs for display
751 CurVersion
= StripEpoch(CurVersion
);
752 CandVersion
= StripEpoch(CandVersion
);
754 // Figure out if its up or down or equal
755 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
756 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
760 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
761 // ---------------------------------------------------------------------
763 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
769 for (const char *I
= Ver
; *I
!= 0; I
++)