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 #include <apt-pkg/progress.h>
00044 #include <apt-pkg/error.h>
00045 
00046 #include <vector>
00047 #include <memory>
00048 #include <set>
00049 
00050 class pkgDepCache : protected pkgCache::Namespace
00051 {
00052    public:
00053 
00055    class InRootSetFunc
00056    {
00057    public:
00058      virtual bool InRootSet(const pkgCache::PkgIterator &pkg) {return false;};
00059      virtual ~InRootSetFunc() {};
00060    };
00061 
00062    private:
00079    void MarkPackage(const pkgCache::PkgIterator &pkg,
00080                     const pkgCache::VerIterator &ver,
00081                     bool const &follow_recommends,
00082                     bool const &follow_suggests);
00083 
00097    bool MarkRequired(InRootSetFunc &rootFunc);
00098 
00108    bool Sweep();
00109 
00110    public:
00111    
00112    // These flags are used in DepState
00113    enum DepFlags {DepNow = (1 << 0),DepInstall = (1 << 1),DepCVer = (1 << 2),
00114                   DepGNow = (1 << 3),DepGInstall = (1 << 4),DepGCVer = (1 << 5)};
00115 
00116    // These flags are used in StateCache::DepState
00117    enum DepStateFlags {DepNowPolicy = (1 << 0), DepNowMin = (1 << 1),
00118                        DepInstPolicy = (1 << 2), DepInstMin = (1 << 3),
00119                        DepCandPolicy = (1 << 4), DepCandMin = (1 << 5)};
00120    
00121    // These flags are used in StateCache::iFlags
00122    enum InternalFlags {AutoKept = (1 << 0), Purge = (1 << 1), ReInstall = (1 << 2), Protected = (1 << 3)};
00123       
00124    enum VersionTypes {NowVersion, InstallVersion, CandidateVersion};
00125    enum ModeList {ModeDelete = 0, ModeKeep = 1, ModeInstall = 2};
00126 
00150    class ActionGroup
00151    {
00152        pkgDepCache &cache;
00153 
00154        bool released;
00155 
00157        ActionGroup(const ActionGroup &other);
00158    public:
00167        ActionGroup(pkgDepCache &cache);
00168 
00173        void release();
00174 
00180        ~ActionGroup();
00181    };
00182 
00186    class DefaultRootSetFunc : public InRootSetFunc, public Configuration::MatchAgainstConfig
00187    {
00188    public:
00189      DefaultRootSetFunc() : Configuration::MatchAgainstConfig("APT::NeverAutoRemove") {};
00190      virtual ~DefaultRootSetFunc() {};
00191 
00192      bool InRootSet(const pkgCache::PkgIterator &pkg) { return pkg.end() == false && Match(pkg.Name()); };
00193    };
00194 
00195    struct StateCache
00196    {
00197       // Epoch stripped text versions of the two version fields
00198       const char *CandVersion;
00199       const char *CurVersion;
00200 
00201       // Pointer to the candidate install version. 
00202       Version *CandidateVer;
00203 
00204       // Pointer to the install version.
00205       Version *InstallVer;
00206       
00207       // Copy of Package::Flags
00208       unsigned short Flags;
00209       unsigned short iFlags;           // Internal flags
00210 
00212       bool Marked;
00213 
00220       bool Garbage;
00221 
00222       // Various tree indicators
00223       signed char Status;              // -1,0,1,2
00224       unsigned char Mode;              // ModeList
00225       unsigned char DepState;          // DepState Flags
00226 
00227       // Update of candidate version
00228       const char *StripEpoch(const char *Ver);
00229       void Update(PkgIterator Pkg,pkgCache &Cache);
00230       
00231       // Various test members for the current status of the package
00232       inline bool NewInstall() const {return Status == 2 && Mode == ModeInstall;};
00233       inline bool Delete() const {return Mode == ModeDelete;};
00234       inline bool Purge() const {return Delete() == true && (iFlags & pkgDepCache::Purge) == pkgDepCache::Purge; };
00235       inline bool Keep() const {return Mode == ModeKeep;};
00236       inline bool Protect() const {return (iFlags & Protected) == Protected;};
00237       inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;};
00238       inline bool Upgradable() const {return Status >= 1;};
00239       inline bool Downgrade() const {return Status < 0 && Mode == ModeInstall;};
00240       inline bool Held() const {return Status != 0 && Keep();};
00241       inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;};
00242       inline bool NowPolicyBroken() const {return (DepState & DepNowPolicy) != DepNowPolicy;};
00243       inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;};
00244       inline bool InstPolicyBroken() const {return (DepState & DepInstPolicy) != DepInstPolicy;};
00245       inline bool Install() const {return Mode == ModeInstall;};
00246       inline bool ReInstall() const {return Delete() == false && (iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall;};
00247       inline VerIterator InstVerIter(pkgCache &Cache)
00248                 {return VerIterator(Cache,InstallVer);};
00249       inline VerIterator CandidateVerIter(pkgCache &Cache)
00250                 {return VerIterator(Cache,CandidateVer);};
00251    };
00252    
00253    // Helper functions
00254    void BuildGroupOrs(VerIterator const &V);
00255    void UpdateVerState(PkgIterator Pkg);
00256 
00257    // User Policy control
00258    class Policy
00259    {
00260       public:
00261       Policy() {
00262          InstallRecommends = _config->FindB("APT::Install-Recommends", false);
00263          InstallSuggests = _config->FindB("APT::Install-Suggests", false);
00264       }
00265 
00266       virtual VerIterator GetCandidateVer(PkgIterator const &Pkg);
00267       virtual bool IsImportantDep(DepIterator const &Dep);
00268       virtual signed short GetPriority(PkgIterator const &Pkg);
00269       virtual signed short GetPriority(PkgFileIterator const &File);
00270 
00271       virtual ~Policy() {};
00272 
00273       private:
00274       bool InstallRecommends;
00275       bool InstallSuggests;
00276    };
00277 
00278    private:
00282    int group_level;
00283 
00284    friend class ActionGroup;
00285      
00286    protected:
00287 
00288    // State information
00289    pkgCache *Cache;
00290    StateCache *PkgState;
00291    unsigned char *DepState;
00292 
00294    signed long long iUsrSize;
00296    unsigned long long iDownloadSize;
00297    unsigned long iInstCount;
00298    unsigned long iDelCount;
00299    unsigned long iKeepCount;
00300    unsigned long iBrokenCount;
00301    unsigned long iPolicyBrokenCount;
00302    unsigned long iBadCount;
00303 
00304    bool DebugMarker;
00305    bool DebugAutoInstall;
00306 
00307    Policy *delLocalPolicy;           // For memory clean up..
00308    Policy *LocalPolicy;
00309    
00310    // Check for a matching provides
00311    bool CheckDep(DepIterator Dep,int Type,PkgIterator &Res);
00312    inline bool CheckDep(DepIterator Dep,int Type)
00313    {
00314       PkgIterator Res(*this,0);
00315       return CheckDep(Dep,Type,Res);
00316    }
00317    
00318    // Computes state information for deps and versions (w/o storing)
00319    unsigned char DependencyState(DepIterator &D);
00320    unsigned char VersionState(DepIterator D,unsigned char Check,
00321                               unsigned char SetMin,
00322                               unsigned char SetPolicy);
00323 
00324    // Recalculates various portions of the cache, call after changing something
00325    void Update(DepIterator Dep);           // Mostly internal
00326    void Update(PkgIterator const &P);
00327    
00328    // Count manipulators
00329    void AddSizes(const PkgIterator &Pkg, bool const Invert = false);
00330    inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg, true);};
00331    void AddStates(const PkgIterator &Pkg, bool const Invert = false);
00332    inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,true);};
00333    
00334    public:
00335 
00336    // Legacy.. We look like a pkgCache
00337    inline operator pkgCache &() {return *Cache;};
00338    inline Header &Head() {return *Cache->HeaderP;};
00339    inline GrpIterator GrpBegin() {return Cache->GrpBegin();};
00340    inline PkgIterator PkgBegin() {return Cache->PkgBegin();};
00341    inline GrpIterator FindGrp(string const &Name) {return Cache->FindGrp(Name);};
00342    inline PkgIterator FindPkg(string const &Name) {return Cache->FindPkg(Name);};
00343    inline PkgIterator FindPkg(string const &Name, string const &Arch) {return Cache->FindPkg(Name, Arch);};
00344 
00345    inline pkgCache &GetCache() {return *Cache;};
00346    inline pkgVersioningSystem &VS() {return *Cache->VS;};
00347    
00348    // Policy implementation
00349    inline VerIterator GetCandidateVer(PkgIterator const &Pkg) {return LocalPolicy->GetCandidateVer(Pkg);};
00350    inline bool IsImportantDep(DepIterator Dep) {return LocalPolicy->IsImportantDep(Dep);};
00351    inline Policy &GetPolicy() {return *LocalPolicy;};
00352    
00353    // Accessors
00354    inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];};
00355    inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];};
00356 
00365    virtual InRootSetFunc *GetRootSetFunc();
00366 
00369    virtual bool MarkFollowsRecommends();
00370 
00373    virtual bool MarkFollowsSuggests();
00374 
00384    bool MarkAndSweep(InRootSetFunc &rootFunc)
00385    {
00386      return MarkRequired(rootFunc) && Sweep();
00387    }
00388 
00389    bool MarkAndSweep()
00390    {
00391      std::auto_ptr<InRootSetFunc> f(GetRootSetFunc());
00392      if(f.get() != NULL)
00393        return MarkAndSweep(*f.get());
00394      else
00395        return false;
00396    }
00397 
00400    // @{
00401    bool MarkKeep(PkgIterator const &Pkg, bool Soft = false,
00402                  bool FromUser = true, unsigned long Depth = 0);
00403    bool MarkDelete(PkgIterator const &Pkg, bool MarkPurge = false,
00404                    unsigned long Depth = 0, bool FromUser = true);
00405    bool MarkInstall(PkgIterator const &Pkg,bool AutoInst = true,
00406                     unsigned long Depth = 0, bool FromUser = true,
00407                     bool ForceImportantDeps = false);
00408    void MarkProtected(PkgIterator const &Pkg) { PkgState[Pkg->ID].iFlags |= Protected; };
00409 
00410    void SetReInstall(PkgIterator const &Pkg,bool To);
00411    void SetCandidateVersion(VerIterator TargetVer);
00412    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
00413                                 std::string const &TargetRel);
00428    bool SetCandidateRelease(pkgCache::VerIterator TargetVer,
00429                             std::string const &TargetRel,
00430                             std::list<std::pair<pkgCache::VerIterator, pkgCache::VerIterator> > &Changed);
00431 
00433    void MarkAuto(const PkgIterator &Pkg, bool Auto);
00434    // @}
00435 
00452    virtual bool IsInstallOk(const PkgIterator &Pkg,bool AutoInst = true,
00453                             unsigned long Depth = 0, bool FromUser = true);
00454 
00471    virtual bool IsDeleteOk(const PkgIterator &Pkg,bool MarkPurge = false,
00472                             unsigned long Depth = 0, bool FromUser = true);
00473 
00474    // read persistent states
00475    bool readStateFile(OpProgress *prog);
00476    bool writeStateFile(OpProgress *prog, bool InstalledOnly=true);
00477    
00478    // Size queries
00479    inline signed long long UsrSize() {return iUsrSize;};
00480    inline unsigned long long DebSize() {return iDownloadSize;};
00481    inline unsigned long DelCount() {return iDelCount;};
00482    inline unsigned long KeepCount() {return iKeepCount;};
00483    inline unsigned long InstCount() {return iInstCount;};
00484    inline unsigned long BrokenCount() {return iBrokenCount;};
00485    inline unsigned long PolicyBrokenCount() {return iPolicyBrokenCount;};
00486    inline unsigned long BadCount() {return iBadCount;};
00487 
00488    bool Init(OpProgress *Prog);
00489    // Generate all state information
00490    void Update(OpProgress *Prog = 0);
00491 
00492    pkgDepCache(pkgCache *Cache,Policy *Plcy = 0);
00493    virtual ~pkgDepCache();
00494 
00495    private:
00496    bool IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
00497                         unsigned long const Depth, bool const FromUser);
00498 };
00499 
00500 #endif