apt @VERSION@
depcache.h
00001 // -*- mode: c++; mode: fold -*-
00002 // Description                                                          /*{{{*/
00003 // $Id: depcache.h,v 1.14 2001/02/20 07:03:17 jgg Exp $
00004 /* ######################################################################
00005 
00006    DepCache - Dependency Extension data for the cache
00007    
00008    This class stores the cache data and a set of extension structures for
00009    monitoring the current state of all the packages. It also generates and
00010    caches the 'install' state of many things. This refers to the state of the
00011    package after an install has been run.
00012 
00013    The StateCache::State field can be -1,0,1,2 which is <,=,>,no current.
00014    StateCache::Mode is which of the 3 fields is active.
00015    
00016    This structure is important to support the readonly status of the cache 
00017    file. When the data is saved the cache will be refereshed from our 
00018    internal rep and written to disk. Then the actual persistant data 
00019    files will be put on the disk.
00020 
00021    Each dependency is compared against 3 target versions to produce to
00022    3 dependency results.
00023      Now - Compared using the Currently install version
00024      Install - Compared using the install version (final state)
00025      CVer - (Candidate Verion) Compared using the Candidate Version
00026    The candidate and now results are used to decide wheather a package
00027    should be automatically installed or if it should be left alone.
00028    
00029    Remember, the Candidate Version is selected based on the distribution
00030    settings for the Package. The Install Version is selected based on the
00031    state (Delete, Keep, Install) field and can be either the Current Version
00032    or the Candidate version.
00033    
00034    The Candidate version is what is shown the 'Install Version' field.
00035    
00036    ##################################################################### */
00037                                                                         /*}}}*/
00038 #ifndef PKGLIB_DEPCACHE_H
00039 #define PKGLIB_DEPCACHE_H
00040 
00041 #include <apt-pkg/configuration.h>
00042 #include <apt-pkg/pkgcache.h>
00043 
00044 #include <vector>
00045 #include <memory>
00046 #include <set>
00047 #include <list>
00048 
00049 class OpProgress;
00050 
00051 class pkgDepCache : protected pkgCache::Namespace
00052 {
00053    public:
00054 
00056    class InRootSetFunc
00057    {
00058    public:
00059      virtual bool InRootSet(const pkgCache::PkgIterator &pkg) {return false;};
00060      virtual ~InRootSetFunc() {};
00061    };
00062 
00063    private:
00080    void MarkPackage(const pkgCache::PkgIterator &pkg,
00081                     const pkgCache::VerIterator &ver,
00082                     bool const &follow_recommends,
00083                     bool const &follow_suggests);
00084 
00098    bool MarkRequired(InRootSetFunc &rootFunc);
00099 
00109    bool Sweep();
00110 
00111    public:
00112    
00113    // These flags are used in DepState
00114    enum DepFlags {DepNow = (1 << 0),DepInstall = (1 << 1),DepCVer = (1 << 2),
00115                   DepGNow = (1 << 3),DepGInstall = (1 << 4),DepGCVer = (1 << 5)};
00116 
00117    // These flags are used in StateCache::DepState
00118    enum DepStateFlags {DepNowPolicy = (1 << 0), DepNowMin = (1 << 1),
00119                        DepInstPolicy = (1 << 2), DepInstMin = (1 << 3),
00120                        DepCandPolicy = (1 << 4), DepCandMin = (1 << 5)};
00121    
00122    // These flags are used in StateCache::iFlags
00123    enum InternalFlags {AutoKept = (1 << 0), Purge = (1 << 1), ReInstall = (1 << 2), Protected = (1 << 3)};
00124       
00125    enum VersionTypes {NowVersion, InstallVersion, CandidateVersion};
00126    enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2};
00127 
00151    class ActionGroup
00152    {
00153        pkgDepCache &cache;
00154 
00155        bool released;
00156 
00158        ActionGroup(const ActionGroup &other);
00159    public:
00168        ActionGroup(pkgDepCache &cache);
00169 
00174        void release();
00175 
00181        ~ActionGroup();
00182    };
00183 
00187    class DefaultRootSetFunc : public InRootSetFunc, public Configuration::MatchAgainstConfig
00188    {
00189    public:
00190      DefaultRootSetFunc() : Configuration::MatchAgainstConfig("APT::NeverAutoRemove") {};
00191      virtual ~DefaultRootSetFunc() {};
00192 
00193      bool InRootSet(const pkgCache::PkgIterator &pkg) { return pkg.end() == false && Match(pkg.Name()); };
00194    };
00195 
00196    struct StateCache
00197    {
00198       // Epoch stripped text versions of the two version fields
00199       const char *CandVersion;
00200       const char *CurVersion;
00201 
00202       // Pointer to the candidate install version. 
00203       Version *CandidateVer;
00204 
00205       // Pointer to the install version.
00206       Version *InstallVer;
00207       
00208       // Copy of Package::Flags
00209       unsigned short Flags;
00210       unsigned short iFlags;           // Internal flags
00211 
00213       bool Marked;
00214 
00221       bool Garbage;
00222 
00223       // Various tree indicators
00224       signed char Status;              // -1,0,1,2
00225       unsigned char Mode;              // ModeList
00226       unsigned char DepState;          // DepState Flags
00227 
00228       // Update of candidate version
00229       const char *StripEpoch(const char *Ver);
00230       void Update(PkgIterator Pkg,pkgCache &Cache);
00231       
00232       // Various test members for the current status of the package
00233       inline bool NewInstall() const {return Status == 2 && Mode == ModeInstall;};
00234       inline bool Delete() const {return Mode == ModeDelete;};
00235       inline bool Purge() const {return Delete() == true && (iFlags & pkgDepCache::Purge) == pkgDepCache::Purge; };
00236       inline bool Keep() const {return Mode == ModeKeep;};
00237       inline bool Protect() const {return (iFlags & Protected) == Protected;};
00238       inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;};
00239       inline bool Upgradable() const {return Status >= 1;};
00240       inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;};
00241       inline bool Held() const {return Status != 0 && Keep();};
00242       inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;};
00243       inline bool NowPolicyBroken() const {return (DepState & DepNowPolicy) != DepNowPolicy;};
00244       inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;};
00245       inline bool InstPolicyBroken() const {return (DepState & DepInstPolicy) != DepInstPolicy;};
00246       inline bool Install() const {return Mode == ModeInstall;};
00247       inline bool ReInstall() const {return Delete() == false && (iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall;};
00248       inline VerIterator InstVerIter(pkgCache &Cache)
00249                 {return VerIterator(Cache,InstallVer);};
00250       inline VerIterator CandidateVerIter(pkgCache &Cache)
00251                 {return VerIterator(Cache,CandidateVer);};
00252    };
00253    
00254    // Helper functions
00255    void BuildGroupOrs(VerIterator const &V);
00256    void UpdateVerState(PkgIterator Pkg);
00257 
00258    // User Policy control
00259    class Policy
00260    {
00261       public:
00262       Policy() {
00263          InstallRecommends = _config->FindB("APT::Install-Recommends", false);
00264          InstallSuggests = _config->FindB("APT::Install-Suggests", false);
00265       }
00266 
00267       virtual VerIterator GetCandidateVer(PkgIterator const &Pkg);
00268       virtual bool IsImportantDep(DepIterator const &Dep);
00269       virtual signed short GetPriority(PkgIterator const &Pkg);
00270       virtual signed short GetPriority(PkgFileIterator const &File);
00271 
00272       virtual ~Policy() {};
00273 
00274       private:
00275       bool InstallRecommends;
00276       bool InstallSuggests;
00277    };
00278 
00279    private:
00283    int group_level;
00284 
00285    friend class ActionGroup;
00286      
00287    protected:
00288 
00289    // State information
00290    pkgCache *Cache;
00291    StateCache *PkgState;
00292    unsigned char *DepState;
00293 
00295    signed long long iUsrSize;
00297    unsigned long long iDownloadSize;
00298    unsigned long iInstCount;
00299    unsigned long iDelCount;
00300    unsigned long iKeepCount;
00301    unsigned long iBrokenCount;
00302    unsigned long iPolicyBrokenCount;
00303    unsigned long iBadCount;
00304 
00305    bool DebugMarker;
00306    bool DebugAutoInstall;
00307 
00308    Policy *delLocalPolicy;           // For memory clean up..
00309    Policy *LocalPolicy;
00310    
00311    // Check for a matching provides
00312    bool CheckDep(DepIterator Dep,int Type,PkgIterator &Res);
00313    inline bool CheckDep(DepIterator Dep,int Type)
00314    {
00315       PkgIterator Res(*this,0);
00316       return CheckDep(Dep,Type,Res);
00317    }
00318    
00319    // Computes state information for deps and versions (w/o storing)
00320    unsigned char DependencyState(DepIterator &D);
00321    unsigned char VersionState(DepIterator D,unsigned char Check,
00322                               unsigned char SetMin,
00323                               unsigned char SetPolicy);
00324 
00325    // Recalculates various portions of the cache, call after changing something
00326    void Update(DepIterator Dep);           // Mostly internal
00327    void Update(PkgIterator const &P);
00328    
00329    // Count manipulators
00330    void AddSizes(const PkgIterator &Pkg, bool const Invert = false);
00331    inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg, true);};
00332    void AddStates(const PkgIterator &Pkg, bool const Invert = false);
00333    inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,true);};
00334    
00335    public:
00336 
00337    // Legacy.. We look like a pkgCache
00338    inline operator pkgCache &() {return *Cache;};
00339    inline Header &Head() {return *Cache->HeaderP;};
00340    inline GrpIterator GrpBegin() {return Cache->GrpBegin();};
00341    inline PkgIterator PkgBegin() {return Cache->PkgBegin();};
00342    inline GrpIterator FindGrp(std::string const &Name) {return Cache->FindGrp(Name);};
00343    inline PkgIterator FindPkg(std::string const &Name) {return Cache->FindPkg(Name);};
00344    inline PkgIterator FindPkg(std::string const &Name, std::string const &Arch) {return Cache->FindPkg(Name, Arch);};
00345 
00346    inline pkgCache &GetCache() {return *Cache;};
00347    inline pkgVersioningSystem &VS() {return *Cache->VS;};
00348    
00349    // Policy implementation
00350    inline VerIterator GetCandidateVer(PkgIterator const &Pkg) {return LocalPolicy->GetCandidateVer(Pkg);};
00351    inline bool IsImportantDep(DepIterator Dep) {return LocalPolicy->IsImportantDep(Dep);};
00352    inline Policy &GetPolicy() {return *LocalPolicy;};
00353    
00354    // Accessors
00355    inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];};
00356    inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];};
00357 
00366    virtual InRootSetFunc *GetRootSetFunc();
00367 
00370    virtual bool MarkFollowsRecommends();
00371 
00374    virtual bool MarkFollowsSuggests();
00375 
00385    bool MarkAndSweep(InRootSetFunc &rootFunc)
00386    {
00387      return MarkRequired(rootFunc) && Sweep();
00388    }
00389 
00390    bool MarkAndSweep()
00391    {
00392      std::auto_ptr<InRootSetFunc> f(GetRootSetFunc());
00393      if(f.get() != NULL)
00394        return MarkAndSweep(*f.get());
00395      else
00396        return false;
00397    }
00398 
00401    // @{
00402    bool MarkKeep(PkgIterator const &Pkg, bool Soft = false,
00403                  bool FromUser = true, unsigned long Depth = 0);
00404    bool MarkDelete(PkgIterator const &Pkg, bool MarkPurge = false,
00405                    unsigned long Depth = 0, bool FromUser = true);
00406    bool MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
00407                     unsigned long Depth = 0, bool FromUser = true,
00408                     bool ForceImportantDeps = false);
00409    void MarkProtected(PkgIterator const &Pkg) { PkgState[Pkg->ID].iFlags |= Protected; };
00410 
00411    void SetReInstall(PkgIterator const &Pkg,bool To);
00412    void SetCandidateVersion(VerIterator TargetVer);
00413    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
00414                                 std::string const &TargetRel);
00429    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
00430                             std::string const &TargetRel,
00431                             std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > &Changed);
00432 
00434    void MarkAuto(const PkgIterator &Pkg, bool Auto);
00435    // @}
00436 
00453    virtual bool IsInstallOk(const PkgIterator &Pkg,bool AutoInst = true,
00454                             unsigned long Depth = 0, bool FromUser = true);
00455 
00472    virtual bool IsDeleteOk(const PkgIterator &Pkg,bool MarkPurge = false,
00473                             unsigned long Depth = 0, bool FromUser = true);
00474 
00475    // read persistent states
00476    bool readStateFile(OpProgress *prog);
00477    bool writeStateFile(OpProgress *prog, bool InstalledOnly=true);
00478    
00479    // Size queries
00480    inline signed long long UsrSize() {return iUsrSize;};
00481    inline unsigned long long DebSize() {return iDownloadSize;};
00482    inline unsigned long DelCount() {return iDelCount;};
00483    inline unsigned long KeepCount() {return iKeepCount;};
00484    inline unsigned long InstCount() {return iInstCount;};
00485    inline unsigned long BrokenCount() {return iBrokenCount;};
00486    inline unsigned long PolicyBrokenCount() {return iPolicyBrokenCount;};
00487    inline unsigned long BadCount() {return iBadCount;};
00488 
00489    bool Init(OpProgress *Prog);
00490    // Generate all state information
00491    void Update(OpProgress *Prog = 0);
00492 
00493    pkgDepCache(pkgCache *Cache,Policy *Plcy = 0);
00494    virtual ~pkgDepCache();
00495 
00496    private:
00497    bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
00498                         unsigned long const Depth, bool const FromUser);
00499 };
00500 
00501 #endif