X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/094a497dd2dba1f47157e07d57f97c338a5ddaa0..36f610f18a9a12c02ba89c6bb84726f7ed3ba7ad:/apt-pkg/depcache.cc diff --git a/apt-pkg/depcache.cc b/apt-pkg/depcache.cc index 71a0d02a2..727f01462 100644 --- a/apt-pkg/depcache.cc +++ b/apt-pkg/depcache.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: depcache.cc,v 1.2 1998/07/12 23:58:24 jgg Exp $ +// $Id: depcache.cc,v 1.15 1999/03/26 07:38:43 jgg Exp $ /* ###################################################################### Dependency Cache - Caches Dependency information. @@ -20,11 +20,17 @@ // DepCache::pkgDepCache - Constructors /*{{{*/ // --------------------------------------------------------------------- /* */ +pkgDepCache::pkgDepCache(MMap &Map,OpProgress &Prog) : + pkgCache(Map), PkgState(0), DepState(0) +{ + if (_error->PendingError() == false) + Init(&Prog); +} pkgDepCache::pkgDepCache(MMap &Map) : - pkgCache(Map), PkgState(0), DepState(0) + pkgCache(Map), PkgState(0), DepState(0) { if (_error->PendingError() == false) - Init(); + Init(0); } /*}}}*/ // DepCache::~pkgDepCache - Destructor /*{{{*/ @@ -36,23 +42,10 @@ pkgDepCache::~pkgDepCache() delete [] DepState; } /*}}}*/ -// DepCache::ReMap - Regenerate the extra data for the new cache /*{{{*/ -// --------------------------------------------------------------------- -/* pkgCache's constructors call this function, but because the object is not - fully constructed at that point it will not result in this function being - called but pkgCache::ReMap will be instead.*/ -bool pkgDepCache::ReMap() -{ - if (pkgCache::ReMap() == false) - return false; - - return Init(); -} - /*}}}*/ // DepCache::Init - Generate the initial extra structures. /*{{{*/ // --------------------------------------------------------------------- /* This allocats the extension buffers and initializes them. */ -bool pkgDepCache::Init() +bool pkgDepCache::Init(OpProgress *Prog) { delete [] PkgState; delete [] DepState; @@ -61,10 +54,21 @@ bool pkgDepCache::Init() memset(PkgState,0,sizeof(*PkgState)*Head().PackageCount); memset(DepState,0,sizeof(*DepState)*Head().DependsCount); + if (Prog != 0) + { + Prog->OverallProgress(0,2*Head().PackageCount,Head().PackageCount, + "Building Dependency Tree"); + Prog->SubProgress(Head().PackageCount,"Candidate Versions"); + } + /* Set the current state of everything. In this state all of the packages are kept exactly as is. See AllUpgrade */ - for (PkgIterator I = PkgBegin(); I.end() != true; I++) + int Done = 0; + for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++) { + if (Prog != 0) + Prog->Progress(Done); + // Find the proper cache slot StateCache &State = PkgState[I->ID]; State.iFlags = 0; @@ -77,7 +81,16 @@ bool pkgDepCache::Init() State.Update(I,*this); } - Update(); + if (Prog != 0) + { + + Prog->OverallProgress(Head().PackageCount,2*Head().PackageCount, + Head().PackageCount, + "Building Dependency Tree"); + Prog->SubProgress(Head().PackageCount,"Dependency Generation"); + } + + Update(Prog); return true; } @@ -91,14 +104,15 @@ pkgDepCache::VerIterator pkgDepCache::GetCandidateVer(PkgIterator Pkg) // Try to use an explicit target if (Pkg->TargetVer == 0) { - /* Not source versions cannot be a candidate version unless they - are already installed */ + /* Not source/not automatic versions cannot be a candidate version + unless they are already installed */ for (VerIterator I = Pkg.VersionList(); I.end() == false; I++) { if (Pkg.CurrentVer() == I) return I; for (VerFileIterator J = I.FileList(); J.end() == false; J++) - if ((J.File()->Flags & Flag::NotSource) == 0) + if ((J.File()->Flags & Flag::NotSource) == 0 && + (J.File()->Flags & Flag::NotAutomatic) == 0) return I; } @@ -201,25 +215,45 @@ void pkgDepCache::AddSizes(const PkgIterator &Pkg,long Mult) { StateCache &P = PkgState[Pkg->ID]; + if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && + P.Keep() == true) + { + iUsrSize += Mult*P.InstVerIter(*this)->InstalledSize; + return; + } + // Compute the size data if (P.NewInstall() == true) { iUsrSize += Mult*P.InstVerIter(*this)->InstalledSize; iDownloadSize += Mult*P.InstVerIter(*this)->Size; + return; } // Upgrading if (Pkg->CurrentVer != 0 && P.InstallVer != (Version *)Pkg.CurrentVer() && P.InstallVer != 0) { - iUsrSize += Mult*(P.InstVerIter(*this)->InstalledSize - - Pkg.CurrentVer()->InstalledSize); + iUsrSize += Mult*((signed)P.InstVerIter(*this)->InstalledSize - + (signed)Pkg.CurrentVer()->InstalledSize); iDownloadSize += Mult*P.InstVerIter(*this)->Size; + return; + } + + // Reinstall + if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack && + P.Delete() == false) + { + iDownloadSize += Mult*P.InstVerIter(*this)->Size; + return; } // Removing if (Pkg->CurrentVer != 0 && P.InstallVer == 0) + { iUsrSize -= Mult*Pkg.CurrentVer()->InstalledSize; + return; + } } /*}}}*/ // DepCache::AddStates - Add the package to the state counter /*{{{*/ @@ -286,6 +320,7 @@ void pkgDepCache::BuildGroupOrs(VerIterator const &V) State = ~State; // Add to the group if we are within an or.. + State &= 0x7; Group |= State; State |= Group << 3; if ((D->CompareOp & Dep::Or) != Dep::Or) @@ -392,7 +427,7 @@ void pkgDepCache::UpdateVerState(PkgIterator Pkg) // --------------------------------------------------------------------- /* This will figure out the state of all the packages and all the dependencies based on the current policy. */ -void pkgDepCache::Update() +void pkgDepCache::Update(OpProgress *Prog) { iUsrSize = 0; iDownloadSize = 0; @@ -403,8 +438,11 @@ void pkgDepCache::Update() iBadCount = 0; // Perform the depends pass - for (PkgIterator I = PkgBegin(); I.end() != true; I++) + int Done = 0; + for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++) { + if (Prog != 0 && Done%20 == 0) + Prog->Progress(Done); for (VerIterator V = I.VersionList(); V.end() != true; V++) { unsigned char Group = 0; @@ -432,6 +470,9 @@ void pkgDepCache::Update() UpdateVerState(I); AddStates(I); } + + if (Prog != 0) + Prog->Progress(Done); } /*}}}*/ // DepCache::Update - Update the deps list of a package /*{{{*/ @@ -549,7 +590,10 @@ void pkgDepCache::MarkDelete(PkgIterator const &Pkg) RemoveSizes(Pkg); RemoveStates(Pkg); - P.Mode = ModeDelete; + if (Pkg->CurrentVer == 0) + P.Mode = ModeKeep; + else + P.Mode = ModeDelete; P.InstallVer = 0; P.Flags &= Flag::Auto; @@ -660,203 +704,6 @@ void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst) } /*}}}*/ -#if 0 -// DepCache::ResolveConflicts - Figure the auto upgrades /*{{{*/ -// --------------------------------------------------------------------- -/* This routine attempts to resolve conflicts generated by automatic - upgrading. It is known as 'Stage 1' but that name isn't as proper anymore. - - It's most important function is during the initial load of APT. The - loading code will mark every package for upgrade to it's candidate version - and then call this routine. This routine will then 'soft keep' every - package that causes conflict, is conflicted, or so on. It is a bit - agressive in that it may unselect more packages in some odd cases - than are strictly necessary but in the case where no packages were - conflicting before it will always produce a system with no packages - conflicting after. - - This routine is also used during state changes that require autoupgrade - scanning. That is, if a new package is marked for install then all packages - that have been soft kept are reconsidered for upgrade. - - It is called with state information about what can be un-upgraded and - what the pre-upgrade install state was. It is expected that the caller - has already marked the desired packages to the install state. Bit 0 is - the original install state and Bit 1 is controls whether the package - should be touched. -*/ -void pkgDepCache::ResolveConflicts(unsigned char *Touched) -{ - bool Again = false; - do - { - Again = false; - for (PkgIterator I = PkgBegin(); I.end() != true; I++) - { - // The package will install OK - if ((PkgState[I->ID].DepState & DepInstMin) == DepInstMin) - continue; - - /* The package was broken before and this upgrade will not - make things better. We simply mark the package for keep - and assume an upgrade attempt will be hopeless. This might - not be ideal. */ - if ((Touched[I->ID] & (1 << 0)) != (1 << 0)) - { - // The package isnt to be touched - if ((Touched[I->ID] & (1 << 1)) == (1 << 1)) - MarkKeep(I,true); - - continue; - } - - // Check to see if not upgrading it will solve the problem - if (I->CurrentVer != 0) - { - // The package isnt to be touched - if ((Touched[I->ID] & (1 << 1)) == (1 << 1)) - { - if (PkgState[I->ID].Mode != ModeKeep) - Again = true; - - MarkKeep(I,true); - } - - /* Check if the package is sill broken. If so then we cant leave - it as is and get a working system. Lets try marking some - depends for 'keep'. This is brutal, it keeps everything in - sight to fix the problem. */ - DepIterator D = I.CurrentVer().DependsList(); - for (;(PkgState[I->ID].DepState & DepInstMin) != DepInstMin && - D.end() != true; D++) - { - // We only worry about critical deps. - if (D.IsCritical() != true) - continue; - - unsigned char State = DepState[D->ID]; - - // This dep never was set before so we dont need to set it now - if ((State & DepNow) != DepNow) - continue; - - // The dep is okay now no worries. - if ((State & DepInstall) == DepInstall) - continue; - - // Locate a target to keep - PkgIterator P(*this); - if (CheckDep(D,NowVersion,P) == true) - { - // We cant touch this package - if ((Touched[P->ID] & (1 << 1)) == (1 << 1)) - MarkKeep(P,true); - } - } - } - } - } - while (Again == true); -} - /*}}}*/ -// DepCache::PromoteAutoKeep - Gentler version of the above /*{{{*/ -// --------------------------------------------------------------------- -/* This is used when installing packages, all it does is attempt to promote - everything that has been auto-kept. It simply promotes everything - irregardless of it having a chance to work and then runs ResolveConflicts - on the result. This allows circular depends loops to work but isn't - terribly fast. */ -void pkgDepCache::PromoteAutoKeep() -{ - /* Initialize the touchd array. Bit 0 is the old install state bit 1 - is the touch value */ - unsigned char *Touch = new unsigned char[Head().PackageCount]; - for (unsigned int I = 0; I != Head().PackageCount; I++) - { - if ((PkgState[I].DepState & DepInstMin) == DepInstMin) - Touch[I] = 1 << 0; - else - Touch[I] = 0; - } - - // This allows circular depends to work - for (PkgIterator I = PkgBegin(); I.end() != true; I++) - { - /* It wasnt installed before or it is not autokept or it is not - upgradeable */ - StateCache &P = PkgState[I->ID]; - if (I->CurrentVer == 0 || P.Mode != ModeKeep || I->VersionList == 0 || - P.CandidateVer == (Version *)I.CurrentVer() || - (P.iFlags & AutoKept) != AutoKept) - continue; - - P.Mode = ModeInstall; - P.InstallVer = P.CandidateVer; - if (P.CandidateVer == (Version *)I.CurrentVer()) - P.Mode = ModeKeep; - - // Okay autoupgrade it. - Touch[I->ID] |= 1 << 1; - } - - Update(); - ResolveConflicts(Touch); - - delete [] Touch; -} - /*}}}*/ -// DepCache::AllUpgrade - Try to upgrade everything /*{{{*/ -// --------------------------------------------------------------------- -/* */ -void pkgDepCache::AllUpgrade() -{ - // Set everything to an upgrade mode - for (PkgIterator I = PkgBegin(); I.end() != true; I++) - { - StateCache &State = PkgState[I->ID]; - - /* We dont upgrade packages marked for deletion or that are - not installed or that don't have an upgrade */ - if (State.Mode == ModeDelete || I->CurrentVer == 0 || - (Version *)I.CurrentVer() == State.CandidateVer) - continue; - - // Set the state to upgrade - State.iFlags = 0; - State.Mode = ModeInstall; - State.InstallVer = State.CandidateVer; - if (State.CandidateVer == (Version *)I.CurrentVer()) - State.Mode = ModeKeep; - - // Do not upgrade things that have the hold flag set. - if (I->SelectedState == State::Hold) - { - State.InstallVer = I.CurrentVer(); - State.Mode = ModeKeep; - } - State.Update(I,*this); - } - - Update(); - - /* Initialize the touchd array. Bit 0 is the old install state bit 1 - is the touch value */ - unsigned char *Touch = new unsigned char[Head().PackageCount]; - for (unsigned int I = 0; I != Head().PackageCount; I++) - { - if ((PkgState[I].DepState & DepNowMin) == DepNowMin) - Touch[I] = (1 << 0) | (1 << 1); - else - Touch[I] = 1 << 1; - } - - // Now downgrade everything that is broken - ResolveConflicts(Touch); - delete [] Touch; -} - /*}}}*/ -#endif - // StateCache::Update - Compute the various static display things /*{{{*/ // --------------------------------------------------------------------- /* This is called whenever the Candidate version changes. */